docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
docs: 300 dpi animations, tuned VP9 encoding, parallel rendering and audit fixes (#192)
* Render documentation animations at 300 DPI with a parallel pipeline
Raise the animation resolution from 800x450 to 2400x1350 (300 DPI, same
8x4.5 figure) so the clips stay crisp on high-density displays, and tune
the VP9 WebM encode (-tune-content screen -row-mt 1 -deadline good
-cpu-used 4) to roughly halve the encode time at the same file size. The
GitHub GIF fallback stays at 640 px.
Add a spawned process-pool renderer for the clips (one grouped task per
clip so each FDTD field is simulated once and reused across its four
language/theme variants), mirroring the figure runner and wired to the
existing --jobs flag; --anim single-clip re-renders and --jobs 1 stay
sequential.
Fold in a set of on-canvas readability fixes: Spanish decimal commas in
the FDTD time readouts, time and phase-caption labels repositioned clear
of tick labels and legends, a legible dark pill behind the ducting
channel-axis label, a mathtext L_W subscript in the two-rooms readout,
and the onset magnifier kept fully inside its panel.
* Re-render the documentation animations at 2400x1350
Regenerate every clip (WebM x four language/theme variants, EN GIF and
poster stills) at the new 300 DPI resolution with the tuned VP9 encode,
and refresh the posters at the matching intrinsic size.
* Link the high-resolution WebM under each docs GIF and resize site embeds
Add a one-line link to the high-resolution WebM of each clip beneath every
animation GIF in the GitHub-facing guides, and update the site <video>
embeds (EN + ES) to the new 2400x1350 intrinsic size. The GIF dimensions
are unchanged.
* docs: clamp the onset magnifier against the left panel edge
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
docs: psychoacoustics and hearing didactics, ISO 9612 dosimeter diagram and verified references (#191)
* docs: ISO 9612 occupational-exposure dosimeter and strategy diagram
Add diagram_dosimeter_iso9612 to the SVG toolkit: a worker wearing a
shoulder-mounted personal sound exposure meter with the microphone about
0.04 m above the shoulder and at least 0.1 m from the most-exposed ear
canal (Clause 12.3), alongside the three measurement strategies drawn as
labelled timelines over an eight-hour working day (task-based, job-based
and full-day, Clauses 9-11). Four deterministic variants (EN/ES, light/dark).
* docs: didactic depth and verified references for the psychoacoustics and hearing guides
Expand the six psychoacoustics and hearing guides (GitHub docs copies):
- tone-prominence: add the TNR and PR equations as display math, a
paragraph on when the two ratios disagree, a figure-code <details>, and
a References section (ECMA-418-1 and ECMA-74 free PDFs).
- tone-audibility: explain how the decisive band is selected and how to
read the extended uncertainty, including the ISO 1996-2 Annex J tonal
adjustment; References (ISO/PAS 20065, ISO 1996-2).
- psychoacoustic-annoyance: formalize the Fastl & Zwicker (2007), Osses
et al. (2016) and SQAT references.
- hearing-threshold: the otologically-normal population, percentile
interpretation, ISO 389-7 edition corrected to 2005; References.
- noise-induced-hearing-loss: NIPTS vs HTLAN vs total-threshold relations
and the fence caveats; References (ISO 1999, Passchier-Vermeer 1974,
NIOSH 98-126).
- occupational-exposure: embed the new ISO 9612 diagram, add
measurement-strategy selection and uncertainty-budget dominance prose;
References (ISO 9612, Directive 2003/10/EC, NIOSH 98-126).
Add the Psychoacoustics and Hearing groups to the global bibliography.
* docs(site): mirror the psychoacoustics and hearing didactics into the EN and ES guides
Mirror the six expanded guides (tone-prominence, tone-audibility,
psychoacoustic-annoyance, hearing-threshold, noise-induced-hearing-loss,
occupational-exposure) into the Astro site, English and Spanish: the new
equations, the didactic prose, the ISO 9612 dosimeter diagram embed and the
References sections, plus the Psychoacoustics and Hearing groups on both
bibliography pages.
* docs: deduplicate the site NIHL prose and align the index edition
Remove a duplicated, truncated copy of the "Three quantities, kept
distinct" block that slipped into the site EN noise-induced-hearing-loss
guide, and update the documentation index to the corrected ISO 389-7:2005
edition.
* docs: refine the psychoacoustics and hearing didactic wording
- Tone prominence: describe TNR and PR separately in the lead-in, since only
TNR compares the tone against the in-band noise while PR compares the middle
critical band with the mean of its neighbours. State both criteria piecewise
(8 dB and 9 dB flat from 1 kHz up) and apply them inclusively with an equal
sign, matching the implementation. Translate the Spanish figure snippet
strings (title, axis labels) to match the rendered figure.
- Hearing threshold: soften the unscreened-population claim to an average
tendency rather than every age or frequency, and tie database B to ISO 1999
as its alternate unscreened reference. Use a more natural Spanish verb for
the 90th percentile.
- Noise-induced hearing loss: present 40 dB of combined loss as an approximate
marker where the HN/120 compression becomes noticeable, not a hard boundary,
since the correction scales with the product of the two components.
- Tone audibility: note that ISO/PAS 20065:2016 is withdrawn and superseded by
ISO/TS 20065:2022, while keeping the implemented 2016 edition provenance.
docs: psychoacoustics and hearing didactics, ISO 9612 dosimeter diagram and verified references (#191)
* docs: ISO 9612 occupational-exposure dosimeter and strategy diagram
Add diagram_dosimeter_iso9612 to the SVG toolkit: a worker wearing a
shoulder-mounted personal sound exposure meter with the microphone about
0.04 m above the shoulder and at least 0.1 m from the most-exposed ear
canal (Clause 12.3), alongside the three measurement strategies drawn as
labelled timelines over an eight-hour working day (task-based, job-based
and full-day, Clauses 9-11). Four deterministic variants (EN/ES, light/dark).
* docs: didactic depth and verified references for the psychoacoustics and hearing guides
Expand the six psychoacoustics and hearing guides (GitHub docs copies):
- tone-prominence: add the TNR and PR equations as display math, a
paragraph on when the two ratios disagree, a figure-code <details>, and
a References section (ECMA-418-1 and ECMA-74 free PDFs).
- tone-audibility: explain how the decisive band is selected and how to
read the extended uncertainty, including the ISO 1996-2 Annex J tonal
adjustment; References (ISO/PAS 20065, ISO 1996-2).
- psychoacoustic-annoyance: formalize the Fastl & Zwicker (2007), Osses
et al. (2016) and SQAT references.
- hearing-threshold: the otologically-normal population, percentile
interpretation, ISO 389-7 edition corrected to 2005; References.
- noise-induced-hearing-loss: NIPTS vs HTLAN vs total-threshold relations
and the fence caveats; References (ISO 1999, Passchier-Vermeer 1974,
NIOSH 98-126).
- occupational-exposure: embed the new ISO 9612 diagram, add
measurement-strategy selection and uncertainty-budget dominance prose;
References (ISO 9612, Directive 2003/10/EC, NIOSH 98-126).
Add the Psychoacoustics and Hearing groups to the global bibliography.
* docs(site): mirror the psychoacoustics and hearing didactics into the EN and ES guides
Mirror the six expanded guides (tone-prominence, tone-audibility,
psychoacoustic-annoyance, hearing-threshold, noise-induced-hearing-loss,
occupational-exposure) into the Astro site, English and Spanish: the new
equations, the didactic prose, the ISO 9612 dosimeter diagram embed and the
References sections, plus the Psychoacoustics and Hearing groups on both
bibliography pages.
* docs: deduplicate the site NIHL prose and align the index edition
Remove a duplicated, truncated copy of the "Three quantities, kept
distinct" block that slipped into the site EN noise-induced-hearing-loss
guide, and update the documentation index to the corrected ISO 389-7:2005
edition.
* docs: refine the psychoacoustics and hearing didactic wording
- Tone prominence: describe TNR and PR separately in the lead-in, since only
TNR compares the tone against the in-band noise while PR compares the middle
critical band with the mean of its neighbours. State both criteria piecewise
(8 dB and 9 dB flat from 1 kHz up) and apply them inclusively with an equal
sign, matching the implementation. Translate the Spanish figure snippet
strings (title, axis labels) to match the rendered figure.
- Hearing threshold: soften the unscreened-population claim to an average
tendency rather than every age or frequency, and tie database B to ISO 1999
as its alternate unscreened reference. Use a more natural Spanish verb for
the 90th percentile.
- Noise-induced hearing loss: present 40 dB of combined loss as an approximate
marker where the HN/120 compression becomes noticeable, not a hard boundary,
since the correction scales with the product of the two components.
- Tone audibility: note that ISO/PAS 20065:2016 is withdrawn and superseded by
ISO/TS 20065:2022, while keeping the implemented 2016 edition provenance.
docs: psychoacoustics and hearing didactics, ISO 9612 dosimeter diagram and verified references (#191)
* docs: ISO 9612 occupational-exposure dosimeter and strategy diagram
Add diagram_dosimeter_iso9612 to the SVG toolkit: a worker wearing a
shoulder-mounted personal sound exposure meter with the microphone about
0.04 m above the shoulder and at least 0.1 m from the most-exposed ear
canal (Clause 12.3), alongside the three measurement strategies drawn as
labelled timelines over an eight-hour working day (task-based, job-based
and full-day, Clauses 9-11). Four deterministic variants (EN/ES, light/dark).
* docs: didactic depth and verified references for the psychoacoustics and hearing guides
Expand the six psychoacoustics and hearing guides (GitHub docs copies):
- tone-prominence: add the TNR and PR equations as display math, a
paragraph on when the two ratios disagree, a figure-code <details>, and
a References section (ECMA-418-1 and ECMA-74 free PDFs).
- tone-audibility: explain how the decisive band is selected and how to
read the extended uncertainty, including the ISO 1996-2 Annex J tonal
adjustment; References (ISO/PAS 20065, ISO 1996-2).
- psychoacoustic-annoyance: formalize the Fastl & Zwicker (2007), Osses
et al. (2016) and SQAT references.
- hearing-threshold: the otologically-normal population, percentile
interpretation, ISO 389-7 edition corrected to 2005; References.
- noise-induced-hearing-loss: NIPTS vs HTLAN vs total-threshold relations
and the fence caveats; References (ISO 1999, Passchier-Vermeer 1974,
NIOSH 98-126).
- occupational-exposure: embed the new ISO 9612 diagram, add
measurement-strategy selection and uncertainty-budget dominance prose;
References (ISO 9612, Directive 2003/10/EC, NIOSH 98-126).
Add the Psychoacoustics and Hearing groups to the global bibliography.
* docs(site): mirror the psychoacoustics and hearing didactics into the EN and ES guides
Mirror the six expanded guides (tone-prominence, tone-audibility,
psychoacoustic-annoyance, hearing-threshold, noise-induced-hearing-loss,
occupational-exposure) into the Astro site, English and Spanish: the new
equations, the didactic prose, the ISO 9612 dosimeter diagram embed and the
References sections, plus the Psychoacoustics and Hearing groups on both
bibliography pages.
* docs: deduplicate the site NIHL prose and align the index edition
Remove a duplicated, truncated copy of the "Three quantities, kept
distinct" block that slipped into the site EN noise-induced-hearing-loss
guide, and update the documentation index to the corrected ISO 389-7:2005
edition.
* docs: refine the psychoacoustics and hearing didactic wording
- Tone prominence: describe TNR and PR separately in the lead-in, since only
TNR compares the tone against the in-band noise while PR compares the middle
critical band with the mean of its neighbours. State both criteria piecewise
(8 dB and 9 dB flat from 1 kHz up) and apply them inclusively with an equal
sign, matching the implementation. Translate the Spanish figure snippet
strings (title, axis labels) to match the rendered figure.
- Hearing threshold: soften the unscreened-population claim to an average
tendency rather than every age or frequency, and tie database B to ISO 1999
as its alternate unscreened reference. Use a more natural Spanish verb for
the 90th percentile.
- Noise-induced hearing loss: present 40 dB of combined loss as an approximate
marker where the HN/120 compression becomes noticeable, not a hard boundary,
since the correction scales with the product of the two components.
- Tone audibility: note that ISO/PAS 20065:2016 is withdrawn and superseded by
ISO/TS 20065:2022, while keeping the implemented 2016 edition provenance.
docs: psychoacoustics and hearing didactics, ISO 9612 dosimeter diagram and verified references (#191)
* docs: ISO 9612 occupational-exposure dosimeter and strategy diagram
Add diagram_dosimeter_iso9612 to the SVG toolkit: a worker wearing a
shoulder-mounted personal sound exposure meter with the microphone about
0.04 m above the shoulder and at least 0.1 m from the most-exposed ear
canal (Clause 12.3), alongside the three measurement strategies drawn as
labelled timelines over an eight-hour working day (task-based, job-based
and full-day, Clauses 9-11). Four deterministic variants (EN/ES, light/dark).
* docs: didactic depth and verified references for the psychoacoustics and hearing guides
Expand the six psychoacoustics and hearing guides (GitHub docs copies):
- tone-prominence: add the TNR and PR equations as display math, a
paragraph on when the two ratios disagree, a figure-code <details>, and
a References section (ECMA-418-1 and ECMA-74 free PDFs).
- tone-audibility: explain how the decisive band is selected and how to
read the extended uncertainty, including the ISO 1996-2 Annex J tonal
adjustment; References (ISO/PAS 20065, ISO 1996-2).
- psychoacoustic-annoyance: formalize the Fastl & Zwicker (2007), Osses
et al. (2016) and SQAT references.
- hearing-threshold: the otologically-normal population, percentile
interpretation, ISO 389-7 edition corrected to 2005; References.
- noise-induced-hearing-loss: NIPTS vs HTLAN vs total-threshold relations
and the fence caveats; References (ISO 1999, Passchier-Vermeer 1974,
NIOSH 98-126).
- occupational-exposure: embed the new ISO 9612 diagram, add
measurement-strategy selection and uncertainty-budget dominance prose;
References (ISO 9612, Directive 2003/10/EC, NIOSH 98-126).
Add the Psychoacoustics and Hearing groups to the global bibliography.
* docs(site): mirror the psychoacoustics and hearing didactics into the EN and ES guides
Mirror the six expanded guides (tone-prominence, tone-audibility,
psychoacoustic-annoyance, hearing-threshold, noise-induced-hearing-loss,
occupational-exposure) into the Astro site, English and Spanish: the new
equations, the didactic prose, the ISO 9612 dosimeter diagram embed and the
References sections, plus the Psychoacoustics and Hearing groups on both
bibliography pages.
* docs: deduplicate the site NIHL prose and align the index edition
Remove a duplicated, truncated copy of the "Three quantities, kept
distinct" block that slipped into the site EN noise-induced-hearing-loss
guide, and update the documentation index to the corrected ISO 389-7:2005
edition.
* docs: refine the psychoacoustics and hearing didactic wording
- Tone prominence: describe TNR and PR separately in the lead-in, since only
TNR compares the tone against the in-band noise while PR compares the middle
critical band with the mean of its neighbours. State both criteria piecewise
(8 dB and 9 dB flat from 1 kHz up) and apply them inclusively with an equal
sign, matching the implementation. Translate the Spanish figure snippet
strings (title, axis labels) to match the rendered figure.
- Hearing threshold: soften the unscreened-population claim to an average
tendency rather than every age or frequency, and tie database B to ISO 1999
as its alternate unscreened reference. Use a more natural Spanish verb for
the 90th percentile.
- Noise-induced hearing loss: present 40 dB of combined loss as an approximate
marker where the HN/120 compression becomes noticeable, not a hard boundary,
since the correction scales with the product of the two components.
- Tone audibility: note that ISO/PAS 20065:2016 is withdrawn and superseded by
ISO/TS 20065:2022, while keeping the implemented 2016 edition provenance.
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
EN 12354-6: sound absorption in enclosed spaces (#107)
* feat: EN 12354-6 sound absorption in enclosed spaces
Add the EN 12354-6:2003 prediction of a room's total equivalent sound
absorption area and reverberation time from the absorption of its
surfaces and objects (the normative Clause 4 model).
The absorption area sums the surface contributions, the object areas and
the air absorption (Formula 1), with the air term Aair = 4*m*V*(1 - psi)
(Formula 2, Table 1), the object fraction psi = sum(Vobj)/V (Formula 3)
and the empirical hard-object area Aobj = Vobj^(2/3) (Formula 4). The
reverberation time follows as T = 55.3/c0 * V*(1 - psi)/A (Formula 5,
the 0.16 factor at c0 = 345.6 m/s). The informative Annex D method for
irregular spaces is out of scope.
New module phonometry.en12354_6 with equivalent_absorption_area,
object_fraction, hard_object_absorption, air_absorption_area,
reverberation_time and the per-band enclosed_space_reverberation
returning a ReverberationResult with .plot(). Conformance report gains
an enclosed-space absorption domain (2 checks, 90 total). Adds the
enclosed-space-absorption guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated digit-exact against the three worked cases of Annex E
(A = 2.26/5.03/10.21 m2, T = 2.1/0.9/0.5 s, and the air-absorption
note Aair = 0.12 m2 -> T = 2.0 s).
* refactor: address review feedback on EN 12354-6
- validation helpers _require_positive/_require_fraction: single error
literal and no negated comparison, still rejecting NaN (SonarCloud
S1192/S1940)
- object_fraction: reject negative object volumes and a fraction >= 1
(Gemini)
- air_absorption_area: validate the object fraction range and a
non-negative attenuation coefficient (Gemini)
- equivalent_absorption_area: reject negative air_area, absorption
coefficients and object areas (Gemini)
- reverberation_time: validate the object fraction range (Gemini)
- enclosed_space_reverberation: clear error when a built-in
air_condition is combined with non-standard frequencies (Gemini)
- diagram + alt text: the speed-of-sound symbol is c0, not co
(CodeRabbit); the diagram now renders it as a proper subscript
- tests: cover the speed_of_sound guard (CodeRabbit), NaN volume, the
physical-range validations and the standard-bands guard
* docs: label the object-array sum in the Formula 1 prose
The third summand of Formula 1 is the standard's object arrays k
(groups of identical objects treated as an absorbing surface), not a
duplicated surface term; name all three indices in the surrounding
prose so the equation reads unambiguously (CodeRabbit).
EN 12354-6: sound absorption in enclosed spaces (#107)
* feat: EN 12354-6 sound absorption in enclosed spaces
Add the EN 12354-6:2003 prediction of a room's total equivalent sound
absorption area and reverberation time from the absorption of its
surfaces and objects (the normative Clause 4 model).
The absorption area sums the surface contributions, the object areas and
the air absorption (Formula 1), with the air term Aair = 4*m*V*(1 - psi)
(Formula 2, Table 1), the object fraction psi = sum(Vobj)/V (Formula 3)
and the empirical hard-object area Aobj = Vobj^(2/3) (Formula 4). The
reverberation time follows as T = 55.3/c0 * V*(1 - psi)/A (Formula 5,
the 0.16 factor at c0 = 345.6 m/s). The informative Annex D method for
irregular spaces is out of scope.
New module phonometry.en12354_6 with equivalent_absorption_area,
object_fraction, hard_object_absorption, air_absorption_area,
reverberation_time and the per-band enclosed_space_reverberation
returning a ReverberationResult with .plot(). Conformance report gains
an enclosed-space absorption domain (2 checks, 90 total). Adds the
enclosed-space-absorption guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated digit-exact against the three worked cases of Annex E
(A = 2.26/5.03/10.21 m2, T = 2.1/0.9/0.5 s, and the air-absorption
note Aair = 0.12 m2 -> T = 2.0 s).
* refactor: address review feedback on EN 12354-6
- validation helpers _require_positive/_require_fraction: single error
literal and no negated comparison, still rejecting NaN (SonarCloud
S1192/S1940)
- object_fraction: reject negative object volumes and a fraction >= 1
(Gemini)
- air_absorption_area: validate the object fraction range and a
non-negative attenuation coefficient (Gemini)
- equivalent_absorption_area: reject negative air_area, absorption
coefficients and object areas (Gemini)
- reverberation_time: validate the object fraction range (Gemini)
- enclosed_space_reverberation: clear error when a built-in
air_condition is combined with non-standard frequencies (Gemini)
- diagram + alt text: the speed-of-sound symbol is c0, not co
(CodeRabbit); the diagram now renders it as a proper subscript
- tests: cover the speed_of_sound guard (CodeRabbit), NaN volume, the
physical-range validations and the standard-bands guard
* docs: label the object-array sum in the Formula 1 prose
The third summand of Formula 1 is the standard's object arrays k
(groups of identical objects treated as an absorbing surface), not a
duplicated surface term; name all three indices in the surrounding
prose so the equation reads unambiguously (CodeRabbit).
EN 12354-6: sound absorption in enclosed spaces (#107)
* feat: EN 12354-6 sound absorption in enclosed spaces
Add the EN 12354-6:2003 prediction of a room's total equivalent sound
absorption area and reverberation time from the absorption of its
surfaces and objects (the normative Clause 4 model).
The absorption area sums the surface contributions, the object areas and
the air absorption (Formula 1), with the air term Aair = 4*m*V*(1 - psi)
(Formula 2, Table 1), the object fraction psi = sum(Vobj)/V (Formula 3)
and the empirical hard-object area Aobj = Vobj^(2/3) (Formula 4). The
reverberation time follows as T = 55.3/c0 * V*(1 - psi)/A (Formula 5,
the 0.16 factor at c0 = 345.6 m/s). The informative Annex D method for
irregular spaces is out of scope.
New module phonometry.en12354_6 with equivalent_absorption_area,
object_fraction, hard_object_absorption, air_absorption_area,
reverberation_time and the per-band enclosed_space_reverberation
returning a ReverberationResult with .plot(). Conformance report gains
an enclosed-space absorption domain (2 checks, 90 total). Adds the
enclosed-space-absorption guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated digit-exact against the three worked cases of Annex E
(A = 2.26/5.03/10.21 m2, T = 2.1/0.9/0.5 s, and the air-absorption
note Aair = 0.12 m2 -> T = 2.0 s).
* refactor: address review feedback on EN 12354-6
- validation helpers _require_positive/_require_fraction: single error
literal and no negated comparison, still rejecting NaN (SonarCloud
S1192/S1940)
- object_fraction: reject negative object volumes and a fraction >= 1
(Gemini)
- air_absorption_area: validate the object fraction range and a
non-negative attenuation coefficient (Gemini)
- equivalent_absorption_area: reject negative air_area, absorption
coefficients and object areas (Gemini)
- reverberation_time: validate the object fraction range (Gemini)
- enclosed_space_reverberation: clear error when a built-in
air_condition is combined with non-standard frequencies (Gemini)
- diagram + alt text: the speed-of-sound symbol is c0, not co
(CodeRabbit); the diagram now renders it as a proper subscript
- tests: cover the speed_of_sound guard (CodeRabbit), NaN volume, the
physical-range validations and the standard-bands guard
* docs: label the object-array sum in the Formula 1 prose
The third summand of Formula 1 is the standard's object arrays k
(groups of identical objects treated as an absorbing surface), not a
duplicated surface term; name all three indices in the surrounding
prose so the equation reads unambiguously (CodeRabbit).
EN 12354-6: sound absorption in enclosed spaces (#107)
* feat: EN 12354-6 sound absorption in enclosed spaces
Add the EN 12354-6:2003 prediction of a room's total equivalent sound
absorption area and reverberation time from the absorption of its
surfaces and objects (the normative Clause 4 model).
The absorption area sums the surface contributions, the object areas and
the air absorption (Formula 1), with the air term Aair = 4*m*V*(1 - psi)
(Formula 2, Table 1), the object fraction psi = sum(Vobj)/V (Formula 3)
and the empirical hard-object area Aobj = Vobj^(2/3) (Formula 4). The
reverberation time follows as T = 55.3/c0 * V*(1 - psi)/A (Formula 5,
the 0.16 factor at c0 = 345.6 m/s). The informative Annex D method for
irregular spaces is out of scope.
New module phonometry.en12354_6 with equivalent_absorption_area,
object_fraction, hard_object_absorption, air_absorption_area,
reverberation_time and the per-band enclosed_space_reverberation
returning a ReverberationResult with .plot(). Conformance report gains
an enclosed-space absorption domain (2 checks, 90 total). Adds the
enclosed-space-absorption guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated digit-exact against the three worked cases of Annex E
(A = 2.26/5.03/10.21 m2, T = 2.1/0.9/0.5 s, and the air-absorption
note Aair = 0.12 m2 -> T = 2.0 s).
* refactor: address review feedback on EN 12354-6
- validation helpers _require_positive/_require_fraction: single error
literal and no negated comparison, still rejecting NaN (SonarCloud
S1192/S1940)
- object_fraction: reject negative object volumes and a fraction >= 1
(Gemini)
- air_absorption_area: validate the object fraction range and a
non-negative attenuation coefficient (Gemini)
- equivalent_absorption_area: reject negative air_area, absorption
coefficients and object areas (Gemini)
- reverberation_time: validate the object fraction range (Gemini)
- enclosed_space_reverberation: clear error when a built-in
air_condition is combined with non-standard frequencies (Gemini)
- diagram + alt text: the speed-of-sound symbol is c0, not co
(CodeRabbit); the diagram now renders it as a proper subscript
- tests: cover the speed_of_sound guard (CodeRabbit), NaN volume, the
physical-range validations and the standard-bands guard
* docs: label the object-array sum in the Formula 1 prose
The third summand of Formula 1 is the standard's object arrays k
(groups of identical objects treated as an absorbing surface), not a
duplicated surface term; name all three indices in the surrounding
prose so the equation reads unambiguously (CodeRabbit).
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
feat: 2D FDTD wave simulation as a public API (phonometry.simulation) (#221)
* feat: 2D FDTD wave simulation as a public API (phonometry.simulation)
Promote the staggered-grid pressure-velocity FDTD engine behind the
documentation animations to the library, following the reference model of
Attenborough & Van Renterghem (2021) chapter 4: fdtd_simulation() returns a
frozen FDTDResult with per-probe pressure histories, optional field
snapshots and .plot(); the FDTD2D stepping engine gains rasterised rigid
obstacle masks and per-side locally reacting real-impedance boundaries
(Eqs. 4.33-4.35) alongside the existing sponge layers, plus the
arbitrary-waveform SignalSource; scripts/fdtd2d.py becomes a re-export shim
so the committed animations render from the library code (verified
bit-identical). Validated against analytic oracles: box and duct
eigenfrequencies, free-field arrival delay and cylindrical decay, the
rigid-wall image echo, the normal-incidence impedance reflection
coefficient, the discrete dispersion relation and second-order convergence.
* test: FDTD conformance checks (rigid-box mode and pulse arrival delay)
Two additive analytic anchors in the conformance report: the (1,1)
eigenfrequency of a 1.0 x 0.7 m rigid box against the closed form
f = (c/2) sqrt(1/lx^2 + 1/ly^2), and the probe-to-probe arrival delay of a
free-field pulse over 0.6 m of air against (r2 - r1)/c.
* docs: FDTD concept figure and pipeline diagram
A single-concept figure from the public result object (a barrier
diffraction snapshot with the source, probes and geometry overlaid next to
the two probe histories, PNG per the raster-figure policy) and an SVG
pipeline diagram of the solver (domain, geometry, sources, leapfrog
update, stability bound, frozen result), both in the four language/theme
variants; existing figures regenerate byte-identically.
* docs: FDTD simulation guide (EN/ES), API reference and indices
A didactic guide in the three documentation trees: what FDTD is (the
staggered leapfrog scheme and the Courant bound), the sources, probes,
obstacles and boundary conditions, when a wave-based simulation is worth
its cost, the 2D line-source limits versus 3D, and the numerical
dispersion resolution rule, with runnable snippets whose printed values are
verified. New Wave simulation sidebar group with its section landing pages,
the generated API pages for phonometry.simulation.fdtd, the curated
api-reference rows, the README index entry, the bibliography cross-links
and the changelog entry.
* refactor: harden FDTD input validation and decompose the solver setup
- Reject multidimensional SignalSource samples instead of silently
flattening them, and require integral counts (sponge_width, steps,
record_every, decimate, snapshot_every, absorbing_layer_cells) and
integral source/probe cell indices: fractional values previously
crashed later inside numpy indexing or silently truncated the cell.
- Reuse a preallocated divergence buffer in the pressure step instead of
allocating a full-grid array every time step.
- Split FDTD2D.__init__, _build_edges and fdtd_simulation into focused
helpers with identical semantics; build boundary specs with
dict.fromkeys; construct test inputs outside pytest.raises blocks.
- Correct the numerical-dispersion prose in the guide, docstring and API
quick table: 10 cells per wavelength bounds the on-axis error at about
1.6 % ((k dx)^2 / 24), about 1.4 % at the default cfl, not below 1 %,
matching Attenborough & Van Renterghem's directional analysis; list
duration as its own parameter and drop the em-dashes from the table.
The default numerical path is bit-identical: a six-run battery (rigid
box, absorbing CW, mixed impedance/obstacle/damping, engine
record/decimate, variable c/rho maps, cfl 0.99 duct) reproduces the
previous arrays exactly (array_equal) and the committed figures
regenerate without churn.
* docs: state the dispersion error sign and the heterogeneous-domain caveat
The leading-order dispersion figure is the magnitude of a negative signed
error, and in a domain with spatially varying sound speed the 10-cell rule
uses the smallest speed while slower cells run at a lower local Courant
number, nearer the small-Courant bound. Stated in the guide (EN/ES), the
GitHub page and the source docstring, with the API page regenerated.
feat: 2D FDTD wave simulation as a public API (phonometry.simulation) (#221)
* feat: 2D FDTD wave simulation as a public API (phonometry.simulation)
Promote the staggered-grid pressure-velocity FDTD engine behind the
documentation animations to the library, following the reference model of
Attenborough & Van Renterghem (2021) chapter 4: fdtd_simulation() returns a
frozen FDTDResult with per-probe pressure histories, optional field
snapshots and .plot(); the FDTD2D stepping engine gains rasterised rigid
obstacle masks and per-side locally reacting real-impedance boundaries
(Eqs. 4.33-4.35) alongside the existing sponge layers, plus the
arbitrary-waveform SignalSource; scripts/fdtd2d.py becomes a re-export shim
so the committed animations render from the library code (verified
bit-identical). Validated against analytic oracles: box and duct
eigenfrequencies, free-field arrival delay and cylindrical decay, the
rigid-wall image echo, the normal-incidence impedance reflection
coefficient, the discrete dispersion relation and second-order convergence.
* test: FDTD conformance checks (rigid-box mode and pulse arrival delay)
Two additive analytic anchors in the conformance report: the (1,1)
eigenfrequency of a 1.0 x 0.7 m rigid box against the closed form
f = (c/2) sqrt(1/lx^2 + 1/ly^2), and the probe-to-probe arrival delay of a
free-field pulse over 0.6 m of air against (r2 - r1)/c.
* docs: FDTD concept figure and pipeline diagram
A single-concept figure from the public result object (a barrier
diffraction snapshot with the source, probes and geometry overlaid next to
the two probe histories, PNG per the raster-figure policy) and an SVG
pipeline diagram of the solver (domain, geometry, sources, leapfrog
update, stability bound, frozen result), both in the four language/theme
variants; existing figures regenerate byte-identically.
* docs: FDTD simulation guide (EN/ES), API reference and indices
A didactic guide in the three documentation trees: what FDTD is (the
staggered leapfrog scheme and the Courant bound), the sources, probes,
obstacles and boundary conditions, when a wave-based simulation is worth
its cost, the 2D line-source limits versus 3D, and the numerical
dispersion resolution rule, with runnable snippets whose printed values are
verified. New Wave simulation sidebar group with its section landing pages,
the generated API pages for phonometry.simulation.fdtd, the curated
api-reference rows, the README index entry, the bibliography cross-links
and the changelog entry.
* refactor: harden FDTD input validation and decompose the solver setup
- Reject multidimensional SignalSource samples instead of silently
flattening them, and require integral counts (sponge_width, steps,
record_every, decimate, snapshot_every, absorbing_layer_cells) and
integral source/probe cell indices: fractional values previously
crashed later inside numpy indexing or silently truncated the cell.
- Reuse a preallocated divergence buffer in the pressure step instead of
allocating a full-grid array every time step.
- Split FDTD2D.__init__, _build_edges and fdtd_simulation into focused
helpers with identical semantics; build boundary specs with
dict.fromkeys; construct test inputs outside pytest.raises blocks.
- Correct the numerical-dispersion prose in the guide, docstring and API
quick table: 10 cells per wavelength bounds the on-axis error at about
1.6 % ((k dx)^2 / 24), about 1.4 % at the default cfl, not below 1 %,
matching Attenborough & Van Renterghem's directional analysis; list
duration as its own parameter and drop the em-dashes from the table.
The default numerical path is bit-identical: a six-run battery (rigid
box, absorbing CW, mixed impedance/obstacle/damping, engine
record/decimate, variable c/rho maps, cfl 0.99 duct) reproduces the
previous arrays exactly (array_equal) and the committed figures
regenerate without churn.
* docs: state the dispersion error sign and the heterogeneous-domain caveat
The leading-order dispersion figure is the magnitude of a negative signed
error, and in a domain with spatially varying sound speed the 10-cell rule
uses the smallest speed while slower cells run at a lower local Courant
number, nearer the small-Courant bound. Stated in the guide (EN/ES), the
GitHub page and the source docstring, with the API page regenerated.
feat: 2D FDTD wave simulation as a public API (phonometry.simulation) (#221)
* feat: 2D FDTD wave simulation as a public API (phonometry.simulation)
Promote the staggered-grid pressure-velocity FDTD engine behind the
documentation animations to the library, following the reference model of
Attenborough & Van Renterghem (2021) chapter 4: fdtd_simulation() returns a
frozen FDTDResult with per-probe pressure histories, optional field
snapshots and .plot(); the FDTD2D stepping engine gains rasterised rigid
obstacle masks and per-side locally reacting real-impedance boundaries
(Eqs. 4.33-4.35) alongside the existing sponge layers, plus the
arbitrary-waveform SignalSource; scripts/fdtd2d.py becomes a re-export shim
so the committed animations render from the library code (verified
bit-identical). Validated against analytic oracles: box and duct
eigenfrequencies, free-field arrival delay and cylindrical decay, the
rigid-wall image echo, the normal-incidence impedance reflection
coefficient, the discrete dispersion relation and second-order convergence.
* test: FDTD conformance checks (rigid-box mode and pulse arrival delay)
Two additive analytic anchors in the conformance report: the (1,1)
eigenfrequency of a 1.0 x 0.7 m rigid box against the closed form
f = (c/2) sqrt(1/lx^2 + 1/ly^2), and the probe-to-probe arrival delay of a
free-field pulse over 0.6 m of air against (r2 - r1)/c.
* docs: FDTD concept figure and pipeline diagram
A single-concept figure from the public result object (a barrier
diffraction snapshot with the source, probes and geometry overlaid next to
the two probe histories, PNG per the raster-figure policy) and an SVG
pipeline diagram of the solver (domain, geometry, sources, leapfrog
update, stability bound, frozen result), both in the four language/theme
variants; existing figures regenerate byte-identically.
* docs: FDTD simulation guide (EN/ES), API reference and indices
A didactic guide in the three documentation trees: what FDTD is (the
staggered leapfrog scheme and the Courant bound), the sources, probes,
obstacles and boundary conditions, when a wave-based simulation is worth
its cost, the 2D line-source limits versus 3D, and the numerical
dispersion resolution rule, with runnable snippets whose printed values are
verified. New Wave simulation sidebar group with its section landing pages,
the generated API pages for phonometry.simulation.fdtd, the curated
api-reference rows, the README index entry, the bibliography cross-links
and the changelog entry.
* refactor: harden FDTD input validation and decompose the solver setup
- Reject multidimensional SignalSource samples instead of silently
flattening them, and require integral counts (sponge_width, steps,
record_every, decimate, snapshot_every, absorbing_layer_cells) and
integral source/probe cell indices: fractional values previously
crashed later inside numpy indexing or silently truncated the cell.
- Reuse a preallocated divergence buffer in the pressure step instead of
allocating a full-grid array every time step.
- Split FDTD2D.__init__, _build_edges and fdtd_simulation into focused
helpers with identical semantics; build boundary specs with
dict.fromkeys; construct test inputs outside pytest.raises blocks.
- Correct the numerical-dispersion prose in the guide, docstring and API
quick table: 10 cells per wavelength bounds the on-axis error at about
1.6 % ((k dx)^2 / 24), about 1.4 % at the default cfl, not below 1 %,
matching Attenborough & Van Renterghem's directional analysis; list
duration as its own parameter and drop the em-dashes from the table.
The default numerical path is bit-identical: a six-run battery (rigid
box, absorbing CW, mixed impedance/obstacle/damping, engine
record/decimate, variable c/rho maps, cfl 0.99 duct) reproduces the
previous arrays exactly (array_equal) and the committed figures
regenerate without churn.
* docs: state the dispersion error sign and the heterogeneous-domain caveat
The leading-order dispersion figure is the magnitude of a negative signed
error, and in a domain with spatially varying sound speed the 10-cell rule
uses the smallest speed while slower cells run at a lower local Courant
number, nearer the small-Courant bound. Stated in the guide (EN/ES), the
GitHub page and the source docstring, with the API page regenerated.
feat: 2D FDTD wave simulation as a public API (phonometry.simulation) (#221)
* feat: 2D FDTD wave simulation as a public API (phonometry.simulation)
Promote the staggered-grid pressure-velocity FDTD engine behind the
documentation animations to the library, following the reference model of
Attenborough & Van Renterghem (2021) chapter 4: fdtd_simulation() returns a
frozen FDTDResult with per-probe pressure histories, optional field
snapshots and .plot(); the FDTD2D stepping engine gains rasterised rigid
obstacle masks and per-side locally reacting real-impedance boundaries
(Eqs. 4.33-4.35) alongside the existing sponge layers, plus the
arbitrary-waveform SignalSource; scripts/fdtd2d.py becomes a re-export shim
so the committed animations render from the library code (verified
bit-identical). Validated against analytic oracles: box and duct
eigenfrequencies, free-field arrival delay and cylindrical decay, the
rigid-wall image echo, the normal-incidence impedance reflection
coefficient, the discrete dispersion relation and second-order convergence.
* test: FDTD conformance checks (rigid-box mode and pulse arrival delay)
Two additive analytic anchors in the conformance report: the (1,1)
eigenfrequency of a 1.0 x 0.7 m rigid box against the closed form
f = (c/2) sqrt(1/lx^2 + 1/ly^2), and the probe-to-probe arrival delay of a
free-field pulse over 0.6 m of air against (r2 - r1)/c.
* docs: FDTD concept figure and pipeline diagram
A single-concept figure from the public result object (a barrier
diffraction snapshot with the source, probes and geometry overlaid next to
the two probe histories, PNG per the raster-figure policy) and an SVG
pipeline diagram of the solver (domain, geometry, sources, leapfrog
update, stability bound, frozen result), both in the four language/theme
variants; existing figures regenerate byte-identically.
* docs: FDTD simulation guide (EN/ES), API reference and indices
A didactic guide in the three documentation trees: what FDTD is (the
staggered leapfrog scheme and the Courant bound), the sources, probes,
obstacles and boundary conditions, when a wave-based simulation is worth
its cost, the 2D line-source limits versus 3D, and the numerical
dispersion resolution rule, with runnable snippets whose printed values are
verified. New Wave simulation sidebar group with its section landing pages,
the generated API pages for phonometry.simulation.fdtd, the curated
api-reference rows, the README index entry, the bibliography cross-links
and the changelog entry.
* refactor: harden FDTD input validation and decompose the solver setup
- Reject multidimensional SignalSource samples instead of silently
flattening them, and require integral counts (sponge_width, steps,
record_every, decimate, snapshot_every, absorbing_layer_cells) and
integral source/probe cell indices: fractional values previously
crashed later inside numpy indexing or silently truncated the cell.
- Reuse a preallocated divergence buffer in the pressure step instead of
allocating a full-grid array every time step.
- Split FDTD2D.__init__, _build_edges and fdtd_simulation into focused
helpers with identical semantics; build boundary specs with
dict.fromkeys; construct test inputs outside pytest.raises blocks.
- Correct the numerical-dispersion prose in the guide, docstring and API
quick table: 10 cells per wavelength bounds the on-axis error at about
1.6 % ((k dx)^2 / 24), about 1.4 % at the default cfl, not below 1 %,
matching Attenborough & Van Renterghem's directional analysis; list
duration as its own parameter and drop the em-dashes from the table.
The default numerical path is bit-identical: a six-run battery (rigid
box, absorbing CW, mixed impedance/obstacle/damping, engine
record/decimate, variable c/rho maps, cfl 0.99 duct) reproduces the
previous arrays exactly (array_equal) and the committed figures
regenerate without churn.
* docs: state the dispersion error sign and the heterogeneous-domain caveat
The leading-order dispersion figure is the magnitude of a negative signed
error, and in a domain with spatially varying sound speed the 10-cell rule
uses the smallest speed while slower cells run at a lower local Courant
number, nearer the small-Courant bound. Stated in the guide (EN/ES), the
GitHub page and the source docstring, with the API page regenerated.
Building acoustics II: facade insulation (ISO 16283-3), laboratory measurement (ISO 10140), prediction with flanking (EN 12354) and uncertainty (ISO 12999-1) (#88)
* feat: ISO 16283-3 facade sound insulation
Add facade_insulation() and FacadeInsulationResult for field facade sound
insulation per ISO 16283-3: the global-method level difference D2m and its
standardized (D2m,nT) and normalized (D2m,n) forms, plus the element-method
apparent sound reduction index R'45 (loudspeaker, -1,5 dB) / R'tr,s (road
traffic, -3 dB). Reuses the ISO 16283-1 energy-averaging helpers, the
Sabine absorption area, and the ISO 717-1 airborne weighted_rating engine
unchanged for the single-number rating. Adds a per-band .plot() profile and
exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 16283-3 draft-edition caveat and symmetric R' validation
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 10140 laboratory airborne and impact sound insulation
Add src/phonometry/lab_insulation.py, the laboratory counterpart of the
field ISO 16283 family:
- lab_airborne_insulation: R = L1 - L2 + 10 lg(S/A) with A = 0,16 V/T
(ISO 10140-2:2010 Formula (2); ISO 10140-4:2010 Formula (5)).
- lab_impact_insulation: Ln = Li + 10 lg(A/A0), A0 = 10 m²
(ISO 10140-3:2010 Formula (1)).
- background_correction: ISO 10140-4:2010 Clause 4.3 Formula (4) with the
6/15 dB criteria and the 1,3 dB limit-of-measurement cap.
Single-number Rw / Ln,w with C, Ctr, CI reuse the verified ISO 717-1/2
weighted_rating / weighted_impact_rating engines; position energy
averaging reuses _as_band_levels. 29 new closed-form / identity tests.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reconcile facade citations with published ISO 16283-3:2016
The facade module was drafted from ISO/DIS 16283-3:2014; its docstrings
cited draft formula numbers with a caveat to reconcile against the
published edition. Reconciled against ISO 16283-3:2016(E) (First edition
2016-02-01):
- Clause numbers are edition-stable: the field-quantity definitions keep
3.12 (R'45deg), 3.13 (R'tr,s), 3.14 (D2m), 3.15 (D2m,nT), 3.16 (D2m,n),
3.17 (A=0,16V/T), and 9.5.1 (surface-level averaging).
- Formula numbers differ: in the 2016 edition the Clause 3 defining
formulas are UNNUMBERED (inline in the term definitions); the numbered
formulas (1)-(21) live in the procedural clauses. The surface-level
energy-average is Formula (7) in 2016 (was Formula (20) in the DIS).
- Dropped the invalid draft Formula (2)-(7) citations from the field-
quantity docstrings and the draft-edition reconciliation caveat.
- Constants and formula bodies are unchanged (-1,5 dB / -3 dB, A0=10 m2,
T0=0,5 s, A=0,16V/T, band ranges): no numeric change; 22 facade tests
green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: EN 12354-1/2 building acoustic performance prediction with flanking
Implement the EN 12354:2000 simplified single-number prediction model for
apparent airborne (R'w) and impact (L'n,w) sound insulation, including direct
plus flanking transmission (Ff/Df/Fd paths) and the Annex E vibration-reduction
index Kij for rigid cross, rigid T, flexible-interlayer and lightweight-facade
junctions.
Airborne Formula (26)/(27)/(28a) with l0=1 m, Kij,min (29), lining composition
(30)/(31); impact Formula (21) with bare-floor Ln,w,eq (164-35 lg m'), Table 1
flanking correction K, and standardized L'nT,w (3). Results expose per-path
energy contributions so the dominant flanking path is visible.
Validated against the standards' worked examples: Part 1 Annex H.3 airborne
(R'w = 52 dB, 13 paths; +floating-floor 53 dB) and Part 2 Annex E.3 impact
(L'n,w = 45 dB, L'nT,w = 43 dB); all four Annex H junctions reproduce Kij.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 12999-1 building acoustics measurement uncertainty
Add building_uncertainty module implementing ISO 12999-1:2020 standard
uncertainties for sound-insulation quantities: per-band and single-number
values for airborne (Tables 2/3), impact (Tables 4/5) and floor-covering
reduction (Tables 6/7), across measurement situations A/B/C (Clause 5.2),
plus the Annex D sigma_R95 upper limits, Table 1 max repeatability and
Table 8 coverage factors.
Expansion U = k*u with k >= 1 (Clause 8), one-sided factors for conformity
checks (Formulae 4/5), and combination rules from Annexes A/B/C (prediction
input A.1, quadrature A.2/C.2, m-measurement reduction A.7, uncorrelated
single-number B.2). Composable UncertainValue attaches value +- U without
touching the rating dataclasses.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: numpy-stub-agnostic annotations for the two env-dependent mypy sites
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: PR-B review minors — anchors, Kij floor, uncertainty polish
- Table 3 r_w+ctr_50_5000 σsitu(B)=1.0 verified digit-by-digit against the
ISO 12999-1:2020(E) page image; anomalous but normative (comment added).
- Anchor the ISO 10140 rating tests to independent literals (Rw=54, Ln,w=58 —
reference-curve shape + the 32 dB / 16-band = 2 dB ISO 717 shift).
- background_correction: cross-ref sound_power.background_noise_correction and
document the negative-margin (Lb > Lsb) cap at Lsb−1.3.
- flanking_path: optional kij_min clamp for EN 12354-1 Clause 4.4.2 (Kij≥Kij,min),
documented on flanking_element; tested clamped vs unclamped (H.3 unaffected).
- impact_flanking_correction: comment on nearest-neighbour + tie-to-lower.
- Export COVERAGE_FACTORS (Table 8) as public API.
- single_number_uncertainty: note impact situation A is an estimate (Table 5 fn a).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: conformance checks for facade, lab insulation, EN 12354 and ISO 12999
Add six numerical conformance checks for the PR-B building-acoustics
standards, following the established registry pattern (single source of
truth in tests/reference_data.py, clause citations, honest tolerances):
- ISO 16283-3:2016 Clause 3.12: facade R'45 isolates the -1.5 dB
oblique-incidence correction on an S=A constructed case (exact).
- ISO 10140-2:2021 Formula (2): lab airborne R laid on the ISO 717-1
reference shape (S=A) -> Rw = 54 (the +2-shift analytic anchor).
- EN 12354-1:2000 Annex H.3: airborne prediction R'w = 52 from the 13
transmission paths (direct + 12 flanking), the branch's strongest oracle.
- EN 12354-2:2000 Annex E.3: impact prediction L'n,w = 45 (76-33+2).
- ISO 12999-1:2020 Table 2: airborne band uncertainty, situation A @
1 kHz = 1.8 dB (digit-exact), and Clause 8/Table 8 expanded
uncertainty U = 1.96 u = 2.352 dB (exact k=1.96 arithmetic).
Facade and lab checks join "Room & building acoustics"; the EN 12354 /
ISO 12999 checks form a new "Building prediction & uncertainty" domain.
Registry grows 26 -> 32 checks across 7 domains. Shared expected values
and the Annex H.3 input table move into reference_data.py so the report
and tests cannot drift; a consistency test pins them to the published
worked-example results. docs/CONFORMANCE.md regenerated via make conformance.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: building acoustics II — facade, laboratory, prediction and uncertainty (EN)
Extend the Room & Building Acoustics guide with facade insulation
(ISO 16283-3), laboratory characterisation (ISO 10140), flanking-transmission
performance prediction (EN 12354-1/2) and measurement uncertainty
(ISO 12999-1), with executed snippets reproducing the EN 12354-1 Annex H.3
(R'w = 52 dB) and Annex E.3 (L'n,w = 45 dB) worked examples. Add the matching
theory subsections, API-reference rows for every new public name, README and
landing-page entries (29 -> 33 standards), and CHANGELOG. EN docs and site
twins keep byte-identical code blocks.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: flanking-paths diagram, prediction and uncertainty figures
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de edificación II (fachadas, laboratorio, predicción, incertidumbre)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: PR-B final-review fixes — count, GitHub-safe math, edition alignment
Landing count corrected to 34 standards (slash-part convention); the
GitHub-unsafe math spacing tokens reintroduced by the new building
sections are scrubbed from the docs/ tree and its site twins; the whole
ISO 10140-2 citation chain aligned to the verified :2010 edition; plus
the six minor documentation-precision fixes from the final review.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 88 review round 1 — isfinite idiom, heading levels, frequencies validation
- building_prediction._check_finite: replace 'v != v or v in (inf,-inf)'
NaN idiom with math.isfinite for SonarCloud (same behavior, cleaner).
- room-acoustics docs (EN docs + site, ES site): relevel the three
parameter-table headings that skipped H2->H4 to H3 (MD001).
- insulation.facade_insulation: validate 'frequencies' length against the
band count, raising a clear ValueError instead of deferring a matplotlib
shape error to plot(). lab_insulation/building_uncertainty have no such
gap (no user-supplied frequencies stored). Regenerated llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Building acoustics II: facade insulation (ISO 16283-3), laboratory measurement (ISO 10140), prediction with flanking (EN 12354) and uncertainty (ISO 12999-1) (#88)
* feat: ISO 16283-3 facade sound insulation
Add facade_insulation() and FacadeInsulationResult for field facade sound
insulation per ISO 16283-3: the global-method level difference D2m and its
standardized (D2m,nT) and normalized (D2m,n) forms, plus the element-method
apparent sound reduction index R'45 (loudspeaker, -1,5 dB) / R'tr,s (road
traffic, -3 dB). Reuses the ISO 16283-1 energy-averaging helpers, the
Sabine absorption area, and the ISO 717-1 airborne weighted_rating engine
unchanged for the single-number rating. Adds a per-band .plot() profile and
exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 16283-3 draft-edition caveat and symmetric R' validation
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 10140 laboratory airborne and impact sound insulation
Add src/phonometry/lab_insulation.py, the laboratory counterpart of the
field ISO 16283 family:
- lab_airborne_insulation: R = L1 - L2 + 10 lg(S/A) with A = 0,16 V/T
(ISO 10140-2:2010 Formula (2); ISO 10140-4:2010 Formula (5)).
- lab_impact_insulation: Ln = Li + 10 lg(A/A0), A0 = 10 m²
(ISO 10140-3:2010 Formula (1)).
- background_correction: ISO 10140-4:2010 Clause 4.3 Formula (4) with the
6/15 dB criteria and the 1,3 dB limit-of-measurement cap.
Single-number Rw / Ln,w with C, Ctr, CI reuse the verified ISO 717-1/2
weighted_rating / weighted_impact_rating engines; position energy
averaging reuses _as_band_levels. 29 new closed-form / identity tests.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reconcile facade citations with published ISO 16283-3:2016
The facade module was drafted from ISO/DIS 16283-3:2014; its docstrings
cited draft formula numbers with a caveat to reconcile against the
published edition. Reconciled against ISO 16283-3:2016(E) (First edition
2016-02-01):
- Clause numbers are edition-stable: the field-quantity definitions keep
3.12 (R'45deg), 3.13 (R'tr,s), 3.14 (D2m), 3.15 (D2m,nT), 3.16 (D2m,n),
3.17 (A=0,16V/T), and 9.5.1 (surface-level averaging).
- Formula numbers differ: in the 2016 edition the Clause 3 defining
formulas are UNNUMBERED (inline in the term definitions); the numbered
formulas (1)-(21) live in the procedural clauses. The surface-level
energy-average is Formula (7) in 2016 (was Formula (20) in the DIS).
- Dropped the invalid draft Formula (2)-(7) citations from the field-
quantity docstrings and the draft-edition reconciliation caveat.
- Constants and formula bodies are unchanged (-1,5 dB / -3 dB, A0=10 m2,
T0=0,5 s, A=0,16V/T, band ranges): no numeric change; 22 facade tests
green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: EN 12354-1/2 building acoustic performance prediction with flanking
Implement the EN 12354:2000 simplified single-number prediction model for
apparent airborne (R'w) and impact (L'n,w) sound insulation, including direct
plus flanking transmission (Ff/Df/Fd paths) and the Annex E vibration-reduction
index Kij for rigid cross, rigid T, flexible-interlayer and lightweight-facade
junctions.
Airborne Formula (26)/(27)/(28a) with l0=1 m, Kij,min (29), lining composition
(30)/(31); impact Formula (21) with bare-floor Ln,w,eq (164-35 lg m'), Table 1
flanking correction K, and standardized L'nT,w (3). Results expose per-path
energy contributions so the dominant flanking path is visible.
Validated against the standards' worked examples: Part 1 Annex H.3 airborne
(R'w = 52 dB, 13 paths; +floating-floor 53 dB) and Part 2 Annex E.3 impact
(L'n,w = 45 dB, L'nT,w = 43 dB); all four Annex H junctions reproduce Kij.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 12999-1 building acoustics measurement uncertainty
Add building_uncertainty module implementing ISO 12999-1:2020 standard
uncertainties for sound-insulation quantities: per-band and single-number
values for airborne (Tables 2/3), impact (Tables 4/5) and floor-covering
reduction (Tables 6/7), across measurement situations A/B/C (Clause 5.2),
plus the Annex D sigma_R95 upper limits, Table 1 max repeatability and
Table 8 coverage factors.
Expansion U = k*u with k >= 1 (Clause 8), one-sided factors for conformity
checks (Formulae 4/5), and combination rules from Annexes A/B/C (prediction
input A.1, quadrature A.2/C.2, m-measurement reduction A.7, uncorrelated
single-number B.2). Composable UncertainValue attaches value +- U without
touching the rating dataclasses.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: numpy-stub-agnostic annotations for the two env-dependent mypy sites
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: PR-B review minors — anchors, Kij floor, uncertainty polish
- Table 3 r_w+ctr_50_5000 σsitu(B)=1.0 verified digit-by-digit against the
ISO 12999-1:2020(E) page image; anomalous but normative (comment added).
- Anchor the ISO 10140 rating tests to independent literals (Rw=54, Ln,w=58 —
reference-curve shape + the 32 dB / 16-band = 2 dB ISO 717 shift).
- background_correction: cross-ref sound_power.background_noise_correction and
document the negative-margin (Lb > Lsb) cap at Lsb−1.3.
- flanking_path: optional kij_min clamp for EN 12354-1 Clause 4.4.2 (Kij≥Kij,min),
documented on flanking_element; tested clamped vs unclamped (H.3 unaffected).
- impact_flanking_correction: comment on nearest-neighbour + tie-to-lower.
- Export COVERAGE_FACTORS (Table 8) as public API.
- single_number_uncertainty: note impact situation A is an estimate (Table 5 fn a).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: conformance checks for facade, lab insulation, EN 12354 and ISO 12999
Add six numerical conformance checks for the PR-B building-acoustics
standards, following the established registry pattern (single source of
truth in tests/reference_data.py, clause citations, honest tolerances):
- ISO 16283-3:2016 Clause 3.12: facade R'45 isolates the -1.5 dB
oblique-incidence correction on an S=A constructed case (exact).
- ISO 10140-2:2021 Formula (2): lab airborne R laid on the ISO 717-1
reference shape (S=A) -> Rw = 54 (the +2-shift analytic anchor).
- EN 12354-1:2000 Annex H.3: airborne prediction R'w = 52 from the 13
transmission paths (direct + 12 flanking), the branch's strongest oracle.
- EN 12354-2:2000 Annex E.3: impact prediction L'n,w = 45 (76-33+2).
- ISO 12999-1:2020 Table 2: airborne band uncertainty, situation A @
1 kHz = 1.8 dB (digit-exact), and Clause 8/Table 8 expanded
uncertainty U = 1.96 u = 2.352 dB (exact k=1.96 arithmetic).
Facade and lab checks join "Room & building acoustics"; the EN 12354 /
ISO 12999 checks form a new "Building prediction & uncertainty" domain.
Registry grows 26 -> 32 checks across 7 domains. Shared expected values
and the Annex H.3 input table move into reference_data.py so the report
and tests cannot drift; a consistency test pins them to the published
worked-example results. docs/CONFORMANCE.md regenerated via make conformance.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: building acoustics II — facade, laboratory, prediction and uncertainty (EN)
Extend the Room & Building Acoustics guide with facade insulation
(ISO 16283-3), laboratory characterisation (ISO 10140), flanking-transmission
performance prediction (EN 12354-1/2) and measurement uncertainty
(ISO 12999-1), with executed snippets reproducing the EN 12354-1 Annex H.3
(R'w = 52 dB) and Annex E.3 (L'n,w = 45 dB) worked examples. Add the matching
theory subsections, API-reference rows for every new public name, README and
landing-page entries (29 -> 33 standards), and CHANGELOG. EN docs and site
twins keep byte-identical code blocks.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: flanking-paths diagram, prediction and uncertainty figures
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de edificación II (fachadas, laboratorio, predicción, incertidumbre)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: PR-B final-review fixes — count, GitHub-safe math, edition alignment
Landing count corrected to 34 standards (slash-part convention); the
GitHub-unsafe math spacing tokens reintroduced by the new building
sections are scrubbed from the docs/ tree and its site twins; the whole
ISO 10140-2 citation chain aligned to the verified :2010 edition; plus
the six minor documentation-precision fixes from the final review.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 88 review round 1 — isfinite idiom, heading levels, frequencies validation
- building_prediction._check_finite: replace 'v != v or v in (inf,-inf)'
NaN idiom with math.isfinite for SonarCloud (same behavior, cleaner).
- room-acoustics docs (EN docs + site, ES site): relevel the three
parameter-table headings that skipped H2->H4 to H3 (MD001).
- insulation.facade_insulation: validate 'frequencies' length against the
band count, raising a clear ValueError instead of deferring a matplotlib
shape error to plot(). lab_insulation/building_uncertainty have no such
gap (no user-supplied frequencies stored). Regenerated llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Building acoustics II: facade insulation (ISO 16283-3), laboratory measurement (ISO 10140), prediction with flanking (EN 12354) and uncertainty (ISO 12999-1) (#88)
* feat: ISO 16283-3 facade sound insulation
Add facade_insulation() and FacadeInsulationResult for field facade sound
insulation per ISO 16283-3: the global-method level difference D2m and its
standardized (D2m,nT) and normalized (D2m,n) forms, plus the element-method
apparent sound reduction index R'45 (loudspeaker, -1,5 dB) / R'tr,s (road
traffic, -3 dB). Reuses the ISO 16283-1 energy-averaging helpers, the
Sabine absorption area, and the ISO 717-1 airborne weighted_rating engine
unchanged for the single-number rating. Adds a per-band .plot() profile and
exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 16283-3 draft-edition caveat and symmetric R' validation
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 10140 laboratory airborne and impact sound insulation
Add src/phonometry/lab_insulation.py, the laboratory counterpart of the
field ISO 16283 family:
- lab_airborne_insulation: R = L1 - L2 + 10 lg(S/A) with A = 0,16 V/T
(ISO 10140-2:2010 Formula (2); ISO 10140-4:2010 Formula (5)).
- lab_impact_insulation: Ln = Li + 10 lg(A/A0), A0 = 10 m²
(ISO 10140-3:2010 Formula (1)).
- background_correction: ISO 10140-4:2010 Clause 4.3 Formula (4) with the
6/15 dB criteria and the 1,3 dB limit-of-measurement cap.
Single-number Rw / Ln,w with C, Ctr, CI reuse the verified ISO 717-1/2
weighted_rating / weighted_impact_rating engines; position energy
averaging reuses _as_band_levels. 29 new closed-form / identity tests.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reconcile facade citations with published ISO 16283-3:2016
The facade module was drafted from ISO/DIS 16283-3:2014; its docstrings
cited draft formula numbers with a caveat to reconcile against the
published edition. Reconciled against ISO 16283-3:2016(E) (First edition
2016-02-01):
- Clause numbers are edition-stable: the field-quantity definitions keep
3.12 (R'45deg), 3.13 (R'tr,s), 3.14 (D2m), 3.15 (D2m,nT), 3.16 (D2m,n),
3.17 (A=0,16V/T), and 9.5.1 (surface-level averaging).
- Formula numbers differ: in the 2016 edition the Clause 3 defining
formulas are UNNUMBERED (inline in the term definitions); the numbered
formulas (1)-(21) live in the procedural clauses. The surface-level
energy-average is Formula (7) in 2016 (was Formula (20) in the DIS).
- Dropped the invalid draft Formula (2)-(7) citations from the field-
quantity docstrings and the draft-edition reconciliation caveat.
- Constants and formula bodies are unchanged (-1,5 dB / -3 dB, A0=10 m2,
T0=0,5 s, A=0,16V/T, band ranges): no numeric change; 22 facade tests
green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: EN 12354-1/2 building acoustic performance prediction with flanking
Implement the EN 12354:2000 simplified single-number prediction model for
apparent airborne (R'w) and impact (L'n,w) sound insulation, including direct
plus flanking transmission (Ff/Df/Fd paths) and the Annex E vibration-reduction
index Kij for rigid cross, rigid T, flexible-interlayer and lightweight-facade
junctions.
Airborne Formula (26)/(27)/(28a) with l0=1 m, Kij,min (29), lining composition
(30)/(31); impact Formula (21) with bare-floor Ln,w,eq (164-35 lg m'), Table 1
flanking correction K, and standardized L'nT,w (3). Results expose per-path
energy contributions so the dominant flanking path is visible.
Validated against the standards' worked examples: Part 1 Annex H.3 airborne
(R'w = 52 dB, 13 paths; +floating-floor 53 dB) and Part 2 Annex E.3 impact
(L'n,w = 45 dB, L'nT,w = 43 dB); all four Annex H junctions reproduce Kij.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 12999-1 building acoustics measurement uncertainty
Add building_uncertainty module implementing ISO 12999-1:2020 standard
uncertainties for sound-insulation quantities: per-band and single-number
values for airborne (Tables 2/3), impact (Tables 4/5) and floor-covering
reduction (Tables 6/7), across measurement situations A/B/C (Clause 5.2),
plus the Annex D sigma_R95 upper limits, Table 1 max repeatability and
Table 8 coverage factors.
Expansion U = k*u with k >= 1 (Clause 8), one-sided factors for conformity
checks (Formulae 4/5), and combination rules from Annexes A/B/C (prediction
input A.1, quadrature A.2/C.2, m-measurement reduction A.7, uncorrelated
single-number B.2). Composable UncertainValue attaches value +- U without
touching the rating dataclasses.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: numpy-stub-agnostic annotations for the two env-dependent mypy sites
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: PR-B review minors — anchors, Kij floor, uncertainty polish
- Table 3 r_w+ctr_50_5000 σsitu(B)=1.0 verified digit-by-digit against the
ISO 12999-1:2020(E) page image; anomalous but normative (comment added).
- Anchor the ISO 10140 rating tests to independent literals (Rw=54, Ln,w=58 —
reference-curve shape + the 32 dB / 16-band = 2 dB ISO 717 shift).
- background_correction: cross-ref sound_power.background_noise_correction and
document the negative-margin (Lb > Lsb) cap at Lsb−1.3.
- flanking_path: optional kij_min clamp for EN 12354-1 Clause 4.4.2 (Kij≥Kij,min),
documented on flanking_element; tested clamped vs unclamped (H.3 unaffected).
- impact_flanking_correction: comment on nearest-neighbour + tie-to-lower.
- Export COVERAGE_FACTORS (Table 8) as public API.
- single_number_uncertainty: note impact situation A is an estimate (Table 5 fn a).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: conformance checks for facade, lab insulation, EN 12354 and ISO 12999
Add six numerical conformance checks for the PR-B building-acoustics
standards, following the established registry pattern (single source of
truth in tests/reference_data.py, clause citations, honest tolerances):
- ISO 16283-3:2016 Clause 3.12: facade R'45 isolates the -1.5 dB
oblique-incidence correction on an S=A constructed case (exact).
- ISO 10140-2:2021 Formula (2): lab airborne R laid on the ISO 717-1
reference shape (S=A) -> Rw = 54 (the +2-shift analytic anchor).
- EN 12354-1:2000 Annex H.3: airborne prediction R'w = 52 from the 13
transmission paths (direct + 12 flanking), the branch's strongest oracle.
- EN 12354-2:2000 Annex E.3: impact prediction L'n,w = 45 (76-33+2).
- ISO 12999-1:2020 Table 2: airborne band uncertainty, situation A @
1 kHz = 1.8 dB (digit-exact), and Clause 8/Table 8 expanded
uncertainty U = 1.96 u = 2.352 dB (exact k=1.96 arithmetic).
Facade and lab checks join "Room & building acoustics"; the EN 12354 /
ISO 12999 checks form a new "Building prediction & uncertainty" domain.
Registry grows 26 -> 32 checks across 7 domains. Shared expected values
and the Annex H.3 input table move into reference_data.py so the report
and tests cannot drift; a consistency test pins them to the published
worked-example results. docs/CONFORMANCE.md regenerated via make conformance.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: building acoustics II — facade, laboratory, prediction and uncertainty (EN)
Extend the Room & Building Acoustics guide with facade insulation
(ISO 16283-3), laboratory characterisation (ISO 10140), flanking-transmission
performance prediction (EN 12354-1/2) and measurement uncertainty
(ISO 12999-1), with executed snippets reproducing the EN 12354-1 Annex H.3
(R'w = 52 dB) and Annex E.3 (L'n,w = 45 dB) worked examples. Add the matching
theory subsections, API-reference rows for every new public name, README and
landing-page entries (29 -> 33 standards), and CHANGELOG. EN docs and site
twins keep byte-identical code blocks.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: flanking-paths diagram, prediction and uncertainty figures
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de edificación II (fachadas, laboratorio, predicción, incertidumbre)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: PR-B final-review fixes — count, GitHub-safe math, edition alignment
Landing count corrected to 34 standards (slash-part convention); the
GitHub-unsafe math spacing tokens reintroduced by the new building
sections are scrubbed from the docs/ tree and its site twins; the whole
ISO 10140-2 citation chain aligned to the verified :2010 edition; plus
the six minor documentation-precision fixes from the final review.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 88 review round 1 — isfinite idiom, heading levels, frequencies validation
- building_prediction._check_finite: replace 'v != v or v in (inf,-inf)'
NaN idiom with math.isfinite for SonarCloud (same behavior, cleaner).
- room-acoustics docs (EN docs + site, ES site): relevel the three
parameter-table headings that skipped H2->H4 to H3 (MD001).
- insulation.facade_insulation: validate 'frequencies' length against the
band count, raising a clear ValueError instead of deferring a matplotlib
shape error to plot(). lab_insulation/building_uncertainty have no such
gap (no user-supplied frequencies stored). Regenerated llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Building acoustics II: facade insulation (ISO 16283-3), laboratory measurement (ISO 10140), prediction with flanking (EN 12354) and uncertainty (ISO 12999-1) (#88)
* feat: ISO 16283-3 facade sound insulation
Add facade_insulation() and FacadeInsulationResult for field facade sound
insulation per ISO 16283-3: the global-method level difference D2m and its
standardized (D2m,nT) and normalized (D2m,n) forms, plus the element-method
apparent sound reduction index R'45 (loudspeaker, -1,5 dB) / R'tr,s (road
traffic, -3 dB). Reuses the ISO 16283-1 energy-averaging helpers, the
Sabine absorption area, and the ISO 717-1 airborne weighted_rating engine
unchanged for the single-number rating. Adds a per-band .plot() profile and
exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 16283-3 draft-edition caveat and symmetric R' validation
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 10140 laboratory airborne and impact sound insulation
Add src/phonometry/lab_insulation.py, the laboratory counterpart of the
field ISO 16283 family:
- lab_airborne_insulation: R = L1 - L2 + 10 lg(S/A) with A = 0,16 V/T
(ISO 10140-2:2010 Formula (2); ISO 10140-4:2010 Formula (5)).
- lab_impact_insulation: Ln = Li + 10 lg(A/A0), A0 = 10 m²
(ISO 10140-3:2010 Formula (1)).
- background_correction: ISO 10140-4:2010 Clause 4.3 Formula (4) with the
6/15 dB criteria and the 1,3 dB limit-of-measurement cap.
Single-number Rw / Ln,w with C, Ctr, CI reuse the verified ISO 717-1/2
weighted_rating / weighted_impact_rating engines; position energy
averaging reuses _as_band_levels. 29 new closed-form / identity tests.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reconcile facade citations with published ISO 16283-3:2016
The facade module was drafted from ISO/DIS 16283-3:2014; its docstrings
cited draft formula numbers with a caveat to reconcile against the
published edition. Reconciled against ISO 16283-3:2016(E) (First edition
2016-02-01):
- Clause numbers are edition-stable: the field-quantity definitions keep
3.12 (R'45deg), 3.13 (R'tr,s), 3.14 (D2m), 3.15 (D2m,nT), 3.16 (D2m,n),
3.17 (A=0,16V/T), and 9.5.1 (surface-level averaging).
- Formula numbers differ: in the 2016 edition the Clause 3 defining
formulas are UNNUMBERED (inline in the term definitions); the numbered
formulas (1)-(21) live in the procedural clauses. The surface-level
energy-average is Formula (7) in 2016 (was Formula (20) in the DIS).
- Dropped the invalid draft Formula (2)-(7) citations from the field-
quantity docstrings and the draft-edition reconciliation caveat.
- Constants and formula bodies are unchanged (-1,5 dB / -3 dB, A0=10 m2,
T0=0,5 s, A=0,16V/T, band ranges): no numeric change; 22 facade tests
green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: EN 12354-1/2 building acoustic performance prediction with flanking
Implement the EN 12354:2000 simplified single-number prediction model for
apparent airborne (R'w) and impact (L'n,w) sound insulation, including direct
plus flanking transmission (Ff/Df/Fd paths) and the Annex E vibration-reduction
index Kij for rigid cross, rigid T, flexible-interlayer and lightweight-facade
junctions.
Airborne Formula (26)/(27)/(28a) with l0=1 m, Kij,min (29), lining composition
(30)/(31); impact Formula (21) with bare-floor Ln,w,eq (164-35 lg m'), Table 1
flanking correction K, and standardized L'nT,w (3). Results expose per-path
energy contributions so the dominant flanking path is visible.
Validated against the standards' worked examples: Part 1 Annex H.3 airborne
(R'w = 52 dB, 13 paths; +floating-floor 53 dB) and Part 2 Annex E.3 impact
(L'n,w = 45 dB, L'nT,w = 43 dB); all four Annex H junctions reproduce Kij.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 12999-1 building acoustics measurement uncertainty
Add building_uncertainty module implementing ISO 12999-1:2020 standard
uncertainties for sound-insulation quantities: per-band and single-number
values for airborne (Tables 2/3), impact (Tables 4/5) and floor-covering
reduction (Tables 6/7), across measurement situations A/B/C (Clause 5.2),
plus the Annex D sigma_R95 upper limits, Table 1 max repeatability and
Table 8 coverage factors.
Expansion U = k*u with k >= 1 (Clause 8), one-sided factors for conformity
checks (Formulae 4/5), and combination rules from Annexes A/B/C (prediction
input A.1, quadrature A.2/C.2, m-measurement reduction A.7, uncorrelated
single-number B.2). Composable UncertainValue attaches value +- U without
touching the rating dataclasses.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: numpy-stub-agnostic annotations for the two env-dependent mypy sites
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: PR-B review minors — anchors, Kij floor, uncertainty polish
- Table 3 r_w+ctr_50_5000 σsitu(B)=1.0 verified digit-by-digit against the
ISO 12999-1:2020(E) page image; anomalous but normative (comment added).
- Anchor the ISO 10140 rating tests to independent literals (Rw=54, Ln,w=58 —
reference-curve shape + the 32 dB / 16-band = 2 dB ISO 717 shift).
- background_correction: cross-ref sound_power.background_noise_correction and
document the negative-margin (Lb > Lsb) cap at Lsb−1.3.
- flanking_path: optional kij_min clamp for EN 12354-1 Clause 4.4.2 (Kij≥Kij,min),
documented on flanking_element; tested clamped vs unclamped (H.3 unaffected).
- impact_flanking_correction: comment on nearest-neighbour + tie-to-lower.
- Export COVERAGE_FACTORS (Table 8) as public API.
- single_number_uncertainty: note impact situation A is an estimate (Table 5 fn a).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: conformance checks for facade, lab insulation, EN 12354 and ISO 12999
Add six numerical conformance checks for the PR-B building-acoustics
standards, following the established registry pattern (single source of
truth in tests/reference_data.py, clause citations, honest tolerances):
- ISO 16283-3:2016 Clause 3.12: facade R'45 isolates the -1.5 dB
oblique-incidence correction on an S=A constructed case (exact).
- ISO 10140-2:2021 Formula (2): lab airborne R laid on the ISO 717-1
reference shape (S=A) -> Rw = 54 (the +2-shift analytic anchor).
- EN 12354-1:2000 Annex H.3: airborne prediction R'w = 52 from the 13
transmission paths (direct + 12 flanking), the branch's strongest oracle.
- EN 12354-2:2000 Annex E.3: impact prediction L'n,w = 45 (76-33+2).
- ISO 12999-1:2020 Table 2: airborne band uncertainty, situation A @
1 kHz = 1.8 dB (digit-exact), and Clause 8/Table 8 expanded
uncertainty U = 1.96 u = 2.352 dB (exact k=1.96 arithmetic).
Facade and lab checks join "Room & building acoustics"; the EN 12354 /
ISO 12999 checks form a new "Building prediction & uncertainty" domain.
Registry grows 26 -> 32 checks across 7 domains. Shared expected values
and the Annex H.3 input table move into reference_data.py so the report
and tests cannot drift; a consistency test pins them to the published
worked-example results. docs/CONFORMANCE.md regenerated via make conformance.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: building acoustics II — facade, laboratory, prediction and uncertainty (EN)
Extend the Room & Building Acoustics guide with facade insulation
(ISO 16283-3), laboratory characterisation (ISO 10140), flanking-transmission
performance prediction (EN 12354-1/2) and measurement uncertainty
(ISO 12999-1), with executed snippets reproducing the EN 12354-1 Annex H.3
(R'w = 52 dB) and Annex E.3 (L'n,w = 45 dB) worked examples. Add the matching
theory subsections, API-reference rows for every new public name, README and
landing-page entries (29 -> 33 standards), and CHANGELOG. EN docs and site
twins keep byte-identical code blocks.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: flanking-paths diagram, prediction and uncertainty figures
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de edificación II (fachadas, laboratorio, predicción, incertidumbre)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: PR-B final-review fixes — count, GitHub-safe math, edition alignment
Landing count corrected to 34 standards (slash-part convention); the
GitHub-unsafe math spacing tokens reintroduced by the new building
sections are scrubbed from the docs/ tree and its site twins; the whole
ISO 10140-2 citation chain aligned to the verified :2010 edition; plus
the six minor documentation-precision fixes from the final review.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 88 review round 1 — isfinite idiom, heading levels, frequencies validation
- building_prediction._check_finite: replace 'v != v or v in (inf,-inf)'
NaN idiom with math.isfinite for SonarCloud (same behavior, cleaner).
- room-acoustics docs (EN docs + site, ES site): relevel the three
parameter-table headings that skipped H2->H4 to H3 (MD001).
- insulation.facade_insulation: validate 'frequencies' length against the
band count, raising a clear ValueError instead of deferring a matplotlib
shape error to plot(). lab_insulation/building_uncertainty have no such
gap (no user-supplied frequencies stored). Regenerated llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
Human vibration exposure (ISO 8041-1, ISO 2631, ISO 5349, Directive 2002/44/EC) (#94)
New `human_vibration` module implementing the ISO 8041-1:2017 master
weighting cascade (all nine weightings Wb/Wc/Wd/We/Wf/Wh/Wj/Wk/Wm),
ISO 2631-1/-2/-4 whole-body metrics (running RMS, MTVV, VDV, MSDV, crest
factor, vibration total value, energy-equivalent acceleration), the
ISO 5349-1/-2 hand-arm A(8) arithmetic and vibration-white-finger latency,
and the Directive 2002/44/EC EAV/ELV assessment. Every result object exposes
.plot(); validated to <0.05% against the ISO 8041-1 Annex B tables and the
ISO 5349-2 Annex E worked examples. Includes docs page, figures, setup
diagram, and 7 conformance checks (100%).
Human vibration exposure (ISO 8041-1, ISO 2631, ISO 5349, Directive 2002/44/EC) (#94)
New `human_vibration` module implementing the ISO 8041-1:2017 master
weighting cascade (all nine weightings Wb/Wc/Wd/We/Wf/Wh/Wj/Wk/Wm),
ISO 2631-1/-2/-4 whole-body metrics (running RMS, MTVV, VDV, MSDV, crest
factor, vibration total value, energy-equivalent acceleration), the
ISO 5349-1/-2 hand-arm A(8) arithmetic and vibration-white-finger latency,
and the Directive 2002/44/EC EAV/ELV assessment. Every result object exposes
.plot(); validated to <0.05% against the ISO 8041-1 Annex B tables and the
ISO 5349-2 Annex E worked examples. Includes docs page, figures, setup
diagram, and 7 conformance checks (100%).
Human vibration exposure (ISO 8041-1, ISO 2631, ISO 5349, Directive 2002/44/EC) (#94)
New `human_vibration` module implementing the ISO 8041-1:2017 master
weighting cascade (all nine weightings Wb/Wc/Wd/We/Wf/Wh/Wj/Wk/Wm),
ISO 2631-1/-2/-4 whole-body metrics (running RMS, MTVV, VDV, MSDV, crest
factor, vibration total value, energy-equivalent acceleration), the
ISO 5349-1/-2 hand-arm A(8) arithmetic and vibration-white-finger latency,
and the Directive 2002/44/EC EAV/ELV assessment. Every result object exposes
.plot(); validated to <0.05% against the ISO 8041-1 Annex B tables and the
ISO 5349-2 Annex E worked examples. Includes docs page, figures, setup
diagram, and 7 conformance checks (100%).
Human vibration exposure (ISO 8041-1, ISO 2631, ISO 5349, Directive 2002/44/EC) (#94)
New `human_vibration` module implementing the ISO 8041-1:2017 master
weighting cascade (all nine weightings Wb/Wc/Wd/We/Wf/Wh/Wj/Wk/Wm),
ISO 2631-1/-2/-4 whole-body metrics (running RMS, MTVV, VDV, MSDV, crest
factor, vibration total value, energy-equivalent acceleration), the
ISO 5349-1/-2 hand-arm A(8) arithmetic and vibration-white-finger latency,
and the Directive 2002/44/EC EAV/ELV assessment. Every result object exposes
.plot(); validated to <0.05% against the ISO 8041-1 Annex B tables and the
ISO 5349-2 Annex E worked examples. Includes docs page, figures, setup
diagram, and 7 conformance checks (100%).
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
Acoustic materials: impedance tube, airflow resistance & sound-absorption rating (ISO 10534-1/-2, ASTM E2611, ISO 9053-1/-2, ISO 11654) (#91)
* feat: impedance tube, airflow resistance and ISO 11654 absorption rating
Clean-room from the standards (no third-party tool referenced):
- impedance_tube.py: ISO 10534-2 two-microphone transfer-function method
(reflection factor, surface impedance/admittance, absorption), ISO 10534-1
standing-wave-ratio method, and ASTM E2611 four-microphone transfer-matrix
method (wave decomposition, two-load/one-load T-matrix, transmission loss,
material wavenumber and characteristic impedance). Kelvin (ISO) vs Celsius
(ASTM) speed-of-sound helpers keep the two sign/unit conventions apart.
- airflow_resistance.py: ISO 9053-1 static method (through-origin quadratic
fit) and ISO 9053-2 alternating method (Formula 2), with R_s in Pa·s/m and
resistivity in Pa·s/m².
- absorption_rating.py: ISO 11654 weighted absorption alpha_w (0.05-grid
reference-curve shift, L/M/H shape indicators, absorption classes A-E),
verified against the Annex A.1/A.2 worked examples.
103 module tests plus public-export checks; physics-identity anchors for the
tube (rigid wall alpha=0, perfect absorber r=0/Z=rhoc, det(T)=1, air-layer
recovery to <1e-9) since neither tube standard prints a numeric example.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* feat: ISO 9053-2 Annex A kappa', materials docs, figures & conformance
Address per-module review of the impedance-tube / materials modules:
- ISO 9053-2:2020 Annex A (normative): implement the heat-conduction-corrected
effective ratio of specific heats kappa' (Formula (A.7)) and the thermal
boundary-layer thickness b (A.4/A.5) as effective_kappa() and
thermal_boundary_layer_thickness(). The Annex A.3 worked example is a
digit-exact oracle (b = 1.83e-3 m, kappa' = 1.370). Fix the misleading
_ADIABATIC_KAPPA citation: 1.4 is the uncorrected adiabatic fallback, not the
Annex A output.
- absorption_rating: delegate .plot() to _plotting.plot_weighted_absorption,
matching the repo idiom (reuses _unfavourable_mask / _new_axes).
- docs/materials.md: new guide covering ISO 11654, ISO 9053-1/-2 and
ISO 10534-1/-2 + ASTM E2611, with runnable examples and three figures
(EN/ES, light/dark). Linked from the docs index.
- Conformance report: five materials checks (ISO 11654 Annex A.1/A.2,
ISO 9053-2 Annex A.3 b + kappa', ISO 10534-1 SWR); shared oracles in
reference_data.py. 48/48 checks pass.
Impedance-tube module review returned Approved (no code changes needed;
the Eq (20) phase citation was verified correct against ISO 10534-1 p.5).
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* docs: experimental-setup diagrams for the materials methods
Add hand-drawn SVG setup diagrams (EN/ES, light/dark) for the new methods,
mirroring the didactic style of the room-acoustics / outdoor diagrams, and
embed them in docs/materials.md:
- Impedance tube (ISO 10534-2): loudspeaker, tube, two flush microphones at
spacing s and distance x1 from the specimen face, rigid backing, incident/
reflected plane waves and the Eq. (17)-(19) relations.
- Four-microphone transmission-loss tube (ASTM E2611): source, two upstream
and two downstream microphones, adjustable two-load termination, the A/B/C/D
travelling waves, and s1/s2/l1/l2/d labelled to match the library's
transfer_matrix_two_load / wave_decomposition parameters (l1, l2 measured
from the specimen front reference plane).
- Airflow resistance (ISO 9053-1/-2): the static rig (specimen, laminar flow
q_v, differential manometer Δp) and the alternating rig (piston 1-4 Hz,
cavity V, specimen/airtight termination, cavity level L_p).
Also apply the whole-branch review's two before-merge items:
- airflow_resistance.py: add the module-level __all__ it was missing.
- impedance_tube.face_quantities: add functional tests (progressive/backward
wave impedance = ±rho*c) so the exported ASTM Eq. (21) helper is covered.
SVG text() now XML-escapes &, < and > so labels may contain them literally.
Diagrams validated by subagent against the standards' figures and the
library's public-API variable names; the ASTM l2 origin was corrected from
the rear to the front specimen face to match the library convention.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: harden ISO 11654 input coercion (bot review)
_coerce now rejects multi-dimensional array input instead of silently
flattening it (CodeRabbit) and rejects non-finite values with a clear message
instead of a cryptic downstream integer-conversion error (Gemini). Adds tests
for both.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
* fix: flag ill-conditioned transfer-matrix solves (bot review)
transfer_matrix_two_load / transfer_matrix_one_load now emit an
ImpedanceTubeWarning when the solve denominator is near-singular relative to
its operands — two insufficiently-different loads (two-load) or a near-resonant
geometry (one-load) — instead of silently propagating inf/nan (CodeRabbit).
Adds tests for both the singular and the well-conditioned case.
Claude-Session: https://claude.ai/code/session_01JJLhQzF5hTdnEi3bfmqnqm
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Room and building acoustics: ISO 18233, ISO 3382-1/2/3, ISO 16283-1 + ISO 717-1 (#81)
* feat: ISO 18233 sweep/MLS impulse-response acquisition
Add src/phonometry/room_ir.py implementing the ISO 18233:2006
deterministic-excitation IR front end: exponential sine sweep with exact
analytic phase (Annex B), linear spectral-division deconvolution with a
Farina inverse-filter option for harmonic separation (B.5), and
maximum-length-sequence generation (LFSR, orders 2-20) with circular
cross-correlation recovery (Annex A).
Validated against closed forms: known IIR bandpass recovered within 0.1 dB
in band (sweep and MLS), ideal chain to a band-limited delta, +3 dB SNR per
sweep-duration doubling (B.6), and all MLS orders verified as true
maximum-length sequences (autocorrelation L / -1).
433 passed, 12 skipped; ruff, mypy --strict and bandit clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382 room acoustic parameters from impulse responses
Add src/phonometry/room_acoustics.py implementing ISO 3382-1:2009 and
ISO 3382-2:2008 analysis of measured impulse responses:
- decay_curve(): Schroeder backward integration of the squared IR
(5.3.3, Eq. 1) with background-noise truncation at the noise/slope
crossing and exponential tail compensation (Eq. 3), broadband or per
IEC 61260 fractional-octave band.
- room_parameters(): per-band EDT (0/-10 dB, A.2.2), T20 (-5/-25 dB)
and T30 (-5/-35 dB) by least-squares fits (ISO 3382-2 Annex C),
clarity C50/C80 (Eq. A.10), definition D50 (Eq. A.11) and centre
time Ts (Eq. A.13), octave bands 125 Hz-4 kHz by default with a
one-third-octave option and a broadband mode.
- Validity flags per the 5.3.3 dynamic-range criterion (noise at least
evaluation range + 15 dB below the IR maximum: 25/35/45 dB) plus the
Annex B curvature indicator C = 100*(T30/T20 - 1).
Tests validate against closed forms for exponential decays (EDT = T20 =
T30 = T within 1 %; C_te = 10*lg(exp(13.8155*te/T) - 1); D50 =
1 - exp(-0.6908/T); Ts = T/13.8155), the exact C50/D50 relation
(Eq. A.12), double-slope decays (EDT < T20 < T30) and noise-driven
validity-flag behaviour, with tolerances far below the Table A.1 JNDs.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* chore: move figure/diagram generators to scripts/
generate_graphs.py and generate_diagrams.py join benchmark_filters.py
and gen_llms.py in scripts/, where dev tooling already lives. Updated
the Makefile graphs target, the sys.path bootstrap in the graph guard
tests and in generate_graphs.py itself (src/ is now one level up), the
CONTRIBUTING instructions and the theme-images.css pointer. Verified:
module loads from the new location and regenerating the SVG diagrams
produces byte-identical output.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3382-3 open-plan office spatial metrics
Add open_plan_metrics() computing the ISO 3382-3:2012 single-number
quantities from a line of workstation measurements: spatial decay rate
D2,S and nominal speech level Lp,A,S,4m (Clause 6.2, Eq.5; 2-16 m
positions on a log-distance regression) and distraction/privacy
distances rD/rP (Clause 6.3; STI-vs-distance linear regression crossing
0,50 and 0,20). Returns a frozen OpenPlanResult; validates the minimum
of four positions (5.2.2) and equal array lengths.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-1 field insulation and ISO 717-1 weighted ratings
Add phonometry.insulation implementing field airborne sound insulation
(ISO 16283-1:2014) and single-number weighted ratings with C/Ctr
(ISO 717-1):
- airborne_insulation: per-band level difference D (Formula (1)),
standardized level difference DnT = D + 10 lg(T/T0) (Formula (2)) and
apparent sound reduction index R' = D + 10 lg(S/A), A = 0,16 V/T
(Formula (4)/(5)); energy-averages microphone positions (Formula (9)).
- weighted_rating: reference-curve shifting method (Clause 4.4, Table 3)
with the 32,0/10,0 dB unfavourable-deviation bound, plus C/Ctr from the
Table 4 spectra (Clause 4.5). Reference values, spectra and method are
identical in the 2013 and 2020 editions.
- energy_average_level: ISO 16283-1 Formula (9) helper.
Verified against the ISO 717-1 Annex C worked example (Rw(C;Ctr) =
30(-2;-3), unfavourable sum 31,8 dB) and exact-bound / tipping edge
cases. 20 new tests; make check green (484 passed, 12 skipped).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: room & building acoustics guide, theory, API and landing (EN)
New "Room & building acoustics" guide (docs/ + Starlight twin) covering the
full measurement chain: ISO 18233 swept-sine/MLS impulse-response acquisition,
ISO 3382-1/2 decay analysis and room parameters (EDT/T20/T30/C50/C80/D50/Ts),
ISO 3382-3 open-plan speech metrics, and ISO 16283-1 / ISO 717-1 field
insulation with weighted ratings. Adds the matching theory section (Schroeder
integration, regression windows, C/D/Ts, D2,S, DnT/R', reference-curve method),
API-reference rows for all new public names, sidebar entry, README highlight +
docs row, EN landing card, CHANGELOG entries, docs index row, and regenerated
llms-full.txt. All snippets validated; site build and make check green.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Schroeder, ISO 717-1 rating and insulation-setup figures
Add three room/building-acoustics documentation figure sets (each in
en/es x light/dark):
- schroeder_decay: synthetic IR, Schroeder backward integration with
EDT/T20/T30 regressions and evaluation ranges (ISO 3382); annotated
values match room_parameters.
- insulation_rating: ISO 717-1 Annex C example with shifted reference
curve, unfavourable-deviation shading and Rw read at 500 Hz; Rw, C,
Ctr and the unfavourable sum come from weighted_rating.
- diagram_insulation_setup: ISO 16283-1 airborne setup plan view with
the normative minimum distances (clauses 7.6 and 7.2.2).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de acústica de salas y edificación
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: terminología UNE — ponderación temporal en lugar de balística (ES)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: markdown/README parity with the site + llms guide coverage
Scrub GitHub-unsafe display math (\, thin-spaces and escaped \{ \}) from
docs/intensity.md and docs/psychoacoustics.md — the only two guides that
missed the GitHub-safe math conversion of PRs #78/#79 — matching the safe
forms already used in docs/theory.md. Align calibration's sensitivity
symbol/formula to the site ($S$, single-line \qquad).
Extend scripts/gen_llms.py PAGES with the three omitted guides
(psychoacoustics, intensity, room-acoustics) and regenerate llms.txt /
llms-full.txt so AI-facing artifacts cover all 14 docs pages.
The guides/references were otherwise already in parity (didactic code
comments, theory sections, tables, and figures from PRs #77/#80 all
present); docs/README index and README highlights/table verified complete.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — open_plan validation, limits rename, Farina caveat, MLS averaging test
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: ISO 18233 measurement-chain diagram and guide fixes
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: fix sweep_signal cross-reference in Farina caveat
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 81 review round 1 — inverse-filter guards, truncation threshold, IR input validation, docs pipeline wording
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: blank lines around CONTRIBUTING fence (MD031)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
docs: final consistency sweep with titled Standards sections and theory references (#202)
* docs: promote closing Standards paragraphs to titled sections
Every guide's closing standards paragraph becomes a proper heading
(## Standards in English, ## Normas in Spanish) across docs/, the site
guides and their Spanish translations, replacing the horizontal rule and
bold-prefix convention. The bibliography pages now describe the new
convention. Content of every paragraph is unchanged.
* docs: add References sections to the domain theory pages
Each theory page (signal analysis, perception and hearing, rooms and
buildings, environment and transport, vibration) now closes with a
References section in English and Spanish, reusing the verified
bibliography entries with support notes tied to the sections of each
page. No new bibliography entries were needed.
* docs: link the bibliography from getting-started and why-phonometry
Getting-started's next-steps list and the closing paragraph of the
why-phonometry comparison now point to the bibliography, in English and
Spanish.
* docs(es): usar "cámara reverberante" en contextos de ISO 354 e ISO 17497
La sala de ensayo de ISO 354 e ISO 17497-1 pasa a llamarse cámara
reverberante en las guías y páginas de teoría en español y en las
etiquetas de los diagramas afectados (dispersión ISO 17497-1 e
ISO 11654), con las variantes SVG regeneradas de forma determinista.
Los contextos de ISO 3741 conservan "sala reverberante".
* docs(es): ISO 3746 es "método de inspección" en la página de teoría
La página de teoría de entorno y transporte alinea el nombre del método
de ISO 3746 con el título de la norma UNE y con la guía de potencia
sonora, que ya decían inspección.
* fix: cite ISO 389-7:2005, the edition actually implemented
The reference-threshold docstrings, theory pages, curated API table and
conformance labels said ISO 389-7:2006; the implemented edition is
ISO 389-7:2005 (EN ISO 389-7:2006 is its European adoption and keeps its
own year). Generated API pages and the conformance report regenerated.
* docs: shorten the high_accuracy table cell in the weighting guide
The oversampling and G-curve details move from the parameter table to
the high-frequency accuracy section, in English and Spanish; the cell
now fits on one line.
* docs: typeset the underwater-propagation formulas as math
The transmission-loss, sonar-equation, seabed-reflection and Wenz
rule-of-fives expressions move from inline code spans to LaTeX math in
the English and Spanish guides and the docs mirror, matching the rest of
the documentation.
* docs: add References sections to loudness, sound quality and multichannel
The three guides now cite their supporting bibliography entries
(Fastl & Zwicker, Fletcher & Munson, ISO 226, IEC 61260-1 and
IEC 61672-1) with per-page support notes, in English and Spanish, and
the bibliographies' cited-by lists are extended accordingly.
* docs(es): última "sala reverberante" pendiente en contexto ISO 17497-1
La frase partida entre líneas de la guía de dispersión superficial se
había escapado del barrido anterior.
* docs: refresh llms-full.txt from the current docs
The committed copy was last generated before the recent documentation
waves; regenerating picks up the didactic pages added since, the new
Standards and References sections and the ISO 389-7:2005 correction.
* docs(site): align the underwater propagation pages with the richer GitHub mirror
docs: final consistency sweep with titled Standards sections and theory references (#202)
* docs: promote closing Standards paragraphs to titled sections
Every guide's closing standards paragraph becomes a proper heading
(## Standards in English, ## Normas in Spanish) across docs/, the site
guides and their Spanish translations, replacing the horizontal rule and
bold-prefix convention. The bibliography pages now describe the new
convention. Content of every paragraph is unchanged.
* docs: add References sections to the domain theory pages
Each theory page (signal analysis, perception and hearing, rooms and
buildings, environment and transport, vibration) now closes with a
References section in English and Spanish, reusing the verified
bibliography entries with support notes tied to the sections of each
page. No new bibliography entries were needed.
* docs: link the bibliography from getting-started and why-phonometry
Getting-started's next-steps list and the closing paragraph of the
why-phonometry comparison now point to the bibliography, in English and
Spanish.
* docs(es): usar "cámara reverberante" en contextos de ISO 354 e ISO 17497
La sala de ensayo de ISO 354 e ISO 17497-1 pasa a llamarse cámara
reverberante en las guías y páginas de teoría en español y en las
etiquetas de los diagramas afectados (dispersión ISO 17497-1 e
ISO 11654), con las variantes SVG regeneradas de forma determinista.
Los contextos de ISO 3741 conservan "sala reverberante".
* docs(es): ISO 3746 es "método de inspección" en la página de teoría
La página de teoría de entorno y transporte alinea el nombre del método
de ISO 3746 con el título de la norma UNE y con la guía de potencia
sonora, que ya decían inspección.
* fix: cite ISO 389-7:2005, the edition actually implemented
The reference-threshold docstrings, theory pages, curated API table and
conformance labels said ISO 389-7:2006; the implemented edition is
ISO 389-7:2005 (EN ISO 389-7:2006 is its European adoption and keeps its
own year). Generated API pages and the conformance report regenerated.
* docs: shorten the high_accuracy table cell in the weighting guide
The oversampling and G-curve details move from the parameter table to
the high-frequency accuracy section, in English and Spanish; the cell
now fits on one line.
* docs: typeset the underwater-propagation formulas as math
The transmission-loss, sonar-equation, seabed-reflection and Wenz
rule-of-fives expressions move from inline code spans to LaTeX math in
the English and Spanish guides and the docs mirror, matching the rest of
the documentation.
* docs: add References sections to loudness, sound quality and multichannel
The three guides now cite their supporting bibliography entries
(Fastl & Zwicker, Fletcher & Munson, ISO 226, IEC 61260-1 and
IEC 61672-1) with per-page support notes, in English and Spanish, and
the bibliographies' cited-by lists are extended accordingly.
* docs(es): última "sala reverberante" pendiente en contexto ISO 17497-1
La frase partida entre líneas de la guía de dispersión superficial se
había escapado del barrido anterior.
* docs: refresh llms-full.txt from the current docs
The committed copy was last generated before the recent documentation
waves; regenerating picks up the didactic pages added since, the new
Standards and References sections and the ISO 389-7:2005 correction.
* docs(site): align the underwater propagation pages with the richer GitHub mirror
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
ISO 2631-5: multiple-shock whole-body vibration (#106)
* feat: ISO 2631-5 multiple-shock whole-body vibration
Add the ISO 2631-5:2018 spinal-response model for whole-body vibration
containing multiple shocks: the normative Clause 5 dose and the Annex C
injury assessment (the vertical z-axis).
A seat-to-spine transfer function (clause 5.2, Formula 1) maps the
measured seat acceleration to the spinal response Az(t); the acceleration
dose Dz = 1.07*(sum Az,i^6)^(1/6) combines the positive response peaks
(Formula 3), scaled to a daily dose (Formula 4/5). Annex C turns the
daily dose into the compressive stress Sd = mz*Dzd (C.1), the
age-cumulated stress variable R (C.3/C.4) and the Weibull probability of
lumbar injury (C.5).
New module phonometry.iso2631_5 with seat_to_spine_transfer,
spinal_response, acceleration_dose, daily_dose(_multi), compression_dose,
injury_risk, injury_probability and the multiple_shock_assessment
convenience returning a MultipleShockResult with .plot(). Conformance
report gains a multiple-shock domain (3 checks, 88 total). Adds the
multiple-shock-vibration guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated against the standard: the seat-to-spine transfer function
reproduces the Annex D 256 Hz digital realization to within the clause
5.2 tolerance, and the Annex C worked example (5 x 40 m/s2, 82 kg male)
gives Dzd=55.97 m/s2, R=1.22 and injury probability 0.37.
* refactor: address review feedback on ISO 2631-5
- response_peaks: vectorize the positive-peak search with NumPy instead
of a Python loop (Gemini, CodeRabbit)
- injury_probability: accept array-like R and return an array or float,
clamping negative R to zero (Gemini)
- multiple_shock_assessment: raise if only one of exposure_time /
measurement_time is given instead of silently skipping the daily-dose
scaling (Gemini, CodeRabbit)
- spinal_response: reject multi-dimensional input with a clear error
(CodeRabbit)
- export static_stress alongside the other Annex C helpers (CodeRabbit)
- figure/plot: use the vectorized injury_probability directly
- tests: assert_allclose over the transfer-function band, use MZ_MALE
and strict zip, cover array probability and the partial-argument guard
- es guide: consistent decimal style in the code comment (CodeRabbit)
* fix: Spanish decimal comma in mathtext figure legends
The decimal-comma pass skips any label containing mathtext ($...$), so
the ISO 2631-5 'Ejemplo $R$ = 1.22' and NT ACOU 112 'Determinante
$K_I$ = 13.0 dB' legends kept a dot in Spanish. Fold the decimal
conversion into the _ES_PATTERNS rules for those labels (CodeRabbit).
ISO 2631-5: multiple-shock whole-body vibration (#106)
* feat: ISO 2631-5 multiple-shock whole-body vibration
Add the ISO 2631-5:2018 spinal-response model for whole-body vibration
containing multiple shocks: the normative Clause 5 dose and the Annex C
injury assessment (the vertical z-axis).
A seat-to-spine transfer function (clause 5.2, Formula 1) maps the
measured seat acceleration to the spinal response Az(t); the acceleration
dose Dz = 1.07*(sum Az,i^6)^(1/6) combines the positive response peaks
(Formula 3), scaled to a daily dose (Formula 4/5). Annex C turns the
daily dose into the compressive stress Sd = mz*Dzd (C.1), the
age-cumulated stress variable R (C.3/C.4) and the Weibull probability of
lumbar injury (C.5).
New module phonometry.iso2631_5 with seat_to_spine_transfer,
spinal_response, acceleration_dose, daily_dose(_multi), compression_dose,
injury_risk, injury_probability and the multiple_shock_assessment
convenience returning a MultipleShockResult with .plot(). Conformance
report gains a multiple-shock domain (3 checks, 88 total). Adds the
multiple-shock-vibration guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated against the standard: the seat-to-spine transfer function
reproduces the Annex D 256 Hz digital realization to within the clause
5.2 tolerance, and the Annex C worked example (5 x 40 m/s2, 82 kg male)
gives Dzd=55.97 m/s2, R=1.22 and injury probability 0.37.
* refactor: address review feedback on ISO 2631-5
- response_peaks: vectorize the positive-peak search with NumPy instead
of a Python loop (Gemini, CodeRabbit)
- injury_probability: accept array-like R and return an array or float,
clamping negative R to zero (Gemini)
- multiple_shock_assessment: raise if only one of exposure_time /
measurement_time is given instead of silently skipping the daily-dose
scaling (Gemini, CodeRabbit)
- spinal_response: reject multi-dimensional input with a clear error
(CodeRabbit)
- export static_stress alongside the other Annex C helpers (CodeRabbit)
- figure/plot: use the vectorized injury_probability directly
- tests: assert_allclose over the transfer-function band, use MZ_MALE
and strict zip, cover array probability and the partial-argument guard
- es guide: consistent decimal style in the code comment (CodeRabbit)
* fix: Spanish decimal comma in mathtext figure legends
The decimal-comma pass skips any label containing mathtext ($...$), so
the ISO 2631-5 'Ejemplo $R$ = 1.22' and NT ACOU 112 'Determinante
$K_I$ = 13.0 dB' legends kept a dot in Spanish. Fold the decimal
conversion into the _ES_PATTERNS rules for those labels (CodeRabbit).
ISO 2631-5: multiple-shock whole-body vibration (#106)
* feat: ISO 2631-5 multiple-shock whole-body vibration
Add the ISO 2631-5:2018 spinal-response model for whole-body vibration
containing multiple shocks: the normative Clause 5 dose and the Annex C
injury assessment (the vertical z-axis).
A seat-to-spine transfer function (clause 5.2, Formula 1) maps the
measured seat acceleration to the spinal response Az(t); the acceleration
dose Dz = 1.07*(sum Az,i^6)^(1/6) combines the positive response peaks
(Formula 3), scaled to a daily dose (Formula 4/5). Annex C turns the
daily dose into the compressive stress Sd = mz*Dzd (C.1), the
age-cumulated stress variable R (C.3/C.4) and the Weibull probability of
lumbar injury (C.5).
New module phonometry.iso2631_5 with seat_to_spine_transfer,
spinal_response, acceleration_dose, daily_dose(_multi), compression_dose,
injury_risk, injury_probability and the multiple_shock_assessment
convenience returning a MultipleShockResult with .plot(). Conformance
report gains a multiple-shock domain (3 checks, 88 total). Adds the
multiple-shock-vibration guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated against the standard: the seat-to-spine transfer function
reproduces the Annex D 256 Hz digital realization to within the clause
5.2 tolerance, and the Annex C worked example (5 x 40 m/s2, 82 kg male)
gives Dzd=55.97 m/s2, R=1.22 and injury probability 0.37.
* refactor: address review feedback on ISO 2631-5
- response_peaks: vectorize the positive-peak search with NumPy instead
of a Python loop (Gemini, CodeRabbit)
- injury_probability: accept array-like R and return an array or float,
clamping negative R to zero (Gemini)
- multiple_shock_assessment: raise if only one of exposure_time /
measurement_time is given instead of silently skipping the daily-dose
scaling (Gemini, CodeRabbit)
- spinal_response: reject multi-dimensional input with a clear error
(CodeRabbit)
- export static_stress alongside the other Annex C helpers (CodeRabbit)
- figure/plot: use the vectorized injury_probability directly
- tests: assert_allclose over the transfer-function band, use MZ_MALE
and strict zip, cover array probability and the partial-argument guard
- es guide: consistent decimal style in the code comment (CodeRabbit)
* fix: Spanish decimal comma in mathtext figure legends
The decimal-comma pass skips any label containing mathtext ($...$), so
the ISO 2631-5 'Ejemplo $R$ = 1.22' and NT ACOU 112 'Determinante
$K_I$ = 13.0 dB' legends kept a dot in Spanish. Fold the decimal
conversion into the _ES_PATTERNS rules for those labels (CodeRabbit).
ISO 2631-5: multiple-shock whole-body vibration (#106)
* feat: ISO 2631-5 multiple-shock whole-body vibration
Add the ISO 2631-5:2018 spinal-response model for whole-body vibration
containing multiple shocks: the normative Clause 5 dose and the Annex C
injury assessment (the vertical z-axis).
A seat-to-spine transfer function (clause 5.2, Formula 1) maps the
measured seat acceleration to the spinal response Az(t); the acceleration
dose Dz = 1.07*(sum Az,i^6)^(1/6) combines the positive response peaks
(Formula 3), scaled to a daily dose (Formula 4/5). Annex C turns the
daily dose into the compressive stress Sd = mz*Dzd (C.1), the
age-cumulated stress variable R (C.3/C.4) and the Weibull probability of
lumbar injury (C.5).
New module phonometry.iso2631_5 with seat_to_spine_transfer,
spinal_response, acceleration_dose, daily_dose(_multi), compression_dose,
injury_risk, injury_probability and the multiple_shock_assessment
convenience returning a MultipleShockResult with .plot(). Conformance
report gains a multiple-shock domain (3 checks, 88 total). Adds the
multiple-shock-vibration guide (repo + EN/ES site) with a figure and a
flow diagram.
Validated against the standard: the seat-to-spine transfer function
reproduces the Annex D 256 Hz digital realization to within the clause
5.2 tolerance, and the Annex C worked example (5 x 40 m/s2, 82 kg male)
gives Dzd=55.97 m/s2, R=1.22 and injury probability 0.37.
* refactor: address review feedback on ISO 2631-5
- response_peaks: vectorize the positive-peak search with NumPy instead
of a Python loop (Gemini, CodeRabbit)
- injury_probability: accept array-like R and return an array or float,
clamping negative R to zero (Gemini)
- multiple_shock_assessment: raise if only one of exposure_time /
measurement_time is given instead of silently skipping the daily-dose
scaling (Gemini, CodeRabbit)
- spinal_response: reject multi-dimensional input with a clear error
(CodeRabbit)
- export static_stress alongside the other Annex C helpers (CodeRabbit)
- figure/plot: use the vectorized injury_probability directly
- tests: assert_allclose over the transfer-function band, use MZ_MALE
and strict zip, cover array probability and the partial-argument guard
- es guide: consistent decimal style in the code comment (CodeRabbit)
* fix: Spanish decimal comma in mathtext figure legends
The decimal-comma pass skips any label containing mathtext ($...$), so
the ISO 2631-5 'Ejemplo $R$ = 1.22' and NT ACOU 112 'Determinante
$K_I$ = 13.0 dB' legends kept a dot in Spanish. Fold the decimal
conversion into the _ES_PATTERNS rules for those labels (CodeRabbit).
docs: speech and electroacoustics didactics, free-field sensitivity diagram and verified references (#190)
* docs: free-field loudspeaker sensitivity setup diagram (IEC 60268-5)
New diagram_loudspeaker_freefield builder in the SVG generator: loudspeaker
on a stand in an anechoic room, amplifier at 2.83 V, dashed reference axis,
measurement microphone at the 1 m reference distance with a drafting
dimension, and the governing sensitivity relations. Four deterministic
variants (EN/ES, light/dark).
* docs: sensitivity-conventions section in the electroacoustics guide
New section on the IEC 60268-4/-5 sensitivity conventions: microphone
sensitivity in mV/Pa and dB re 1 V/Pa with the reference pitfall, and the
loudspeaker characteristic sensitivity with its electrical (2.83 V vs 1 W)
and geometric (1 m reference distance, inverse-distance referral)
normalizations. Embeds the new setup diagram, adds a References section
(Beranek & Mellow) and extends the Standards footer. EN docs, site EN and
site ES.
* docs: MTF intuition and method pitfalls in the speech-transmission guide
Why modulation depth carries intelligibility (envelope valleys, the 7x14
m(F) grid, the effective-SNR mapping), and a direct-vs-indirect subsection
with the pitfalls the standard is explicit about: non-linear and
time-variant channels, level-dependent masking, impulsive and fluctuating
background noise, and the statistical spread of repeated STIPA runs. Adds a
References section (Houtgast & Steeneken 1985). EN docs, site EN and
site ES.
* docs: band-importance meaning and SII vs STI comparison in the SII guide
What the band-importance function means (the French & Steinberg
articulation lineage; intelligibility vs speech power across bands) and a
new SII-or-STI section with a comparison table of questions answered,
inputs, band machinery, blind spots and typical uses. Adds a References
section (French & Steinberg 1947). EN docs, site EN and site ES.
* docs: Speech group in the bibliography
Houtgast & Steeneken (1985) and French & Steinberg (1947) with verified
DOIs and back-links to the guides that cite them; Cited-by line for
Beranek & Mellow from the electroacoustics guide.
docs: speech and electroacoustics didactics, free-field sensitivity diagram and verified references (#190)
* docs: free-field loudspeaker sensitivity setup diagram (IEC 60268-5)
New diagram_loudspeaker_freefield builder in the SVG generator: loudspeaker
on a stand in an anechoic room, amplifier at 2.83 V, dashed reference axis,
measurement microphone at the 1 m reference distance with a drafting
dimension, and the governing sensitivity relations. Four deterministic
variants (EN/ES, light/dark).
* docs: sensitivity-conventions section in the electroacoustics guide
New section on the IEC 60268-4/-5 sensitivity conventions: microphone
sensitivity in mV/Pa and dB re 1 V/Pa with the reference pitfall, and the
loudspeaker characteristic sensitivity with its electrical (2.83 V vs 1 W)
and geometric (1 m reference distance, inverse-distance referral)
normalizations. Embeds the new setup diagram, adds a References section
(Beranek & Mellow) and extends the Standards footer. EN docs, site EN and
site ES.
* docs: MTF intuition and method pitfalls in the speech-transmission guide
Why modulation depth carries intelligibility (envelope valleys, the 7x14
m(F) grid, the effective-SNR mapping), and a direct-vs-indirect subsection
with the pitfalls the standard is explicit about: non-linear and
time-variant channels, level-dependent masking, impulsive and fluctuating
background noise, and the statistical spread of repeated STIPA runs. Adds a
References section (Houtgast & Steeneken 1985). EN docs, site EN and
site ES.
* docs: band-importance meaning and SII vs STI comparison in the SII guide
What the band-importance function means (the French & Steinberg
articulation lineage; intelligibility vs speech power across bands) and a
new SII-or-STI section with a comparison table of questions answered,
inputs, band machinery, blind spots and typical uses. Adds a References
section (French & Steinberg 1947). EN docs, site EN and site ES.
* docs: Speech group in the bibliography
Houtgast & Steeneken (1985) and French & Steinberg (1947) with verified
DOIs and back-links to the guides that cite them; Cited-by line for
Beranek & Mellow from the electroacoustics guide.
docs: speech and electroacoustics didactics, free-field sensitivity diagram and verified references (#190)
* docs: free-field loudspeaker sensitivity setup diagram (IEC 60268-5)
New diagram_loudspeaker_freefield builder in the SVG generator: loudspeaker
on a stand in an anechoic room, amplifier at 2.83 V, dashed reference axis,
measurement microphone at the 1 m reference distance with a drafting
dimension, and the governing sensitivity relations. Four deterministic
variants (EN/ES, light/dark).
* docs: sensitivity-conventions section in the electroacoustics guide
New section on the IEC 60268-4/-5 sensitivity conventions: microphone
sensitivity in mV/Pa and dB re 1 V/Pa with the reference pitfall, and the
loudspeaker characteristic sensitivity with its electrical (2.83 V vs 1 W)
and geometric (1 m reference distance, inverse-distance referral)
normalizations. Embeds the new setup diagram, adds a References section
(Beranek & Mellow) and extends the Standards footer. EN docs, site EN and
site ES.
* docs: MTF intuition and method pitfalls in the speech-transmission guide
Why modulation depth carries intelligibility (envelope valleys, the 7x14
m(F) grid, the effective-SNR mapping), and a direct-vs-indirect subsection
with the pitfalls the standard is explicit about: non-linear and
time-variant channels, level-dependent masking, impulsive and fluctuating
background noise, and the statistical spread of repeated STIPA runs. Adds a
References section (Houtgast & Steeneken 1985). EN docs, site EN and
site ES.
* docs: band-importance meaning and SII vs STI comparison in the SII guide
What the band-importance function means (the French & Steinberg
articulation lineage; intelligibility vs speech power across bands) and a
new SII-or-STI section with a comparison table of questions answered,
inputs, band machinery, blind spots and typical uses. Adds a References
section (French & Steinberg 1947). EN docs, site EN and site ES.
* docs: Speech group in the bibliography
Houtgast & Steeneken (1985) and French & Steinberg (1947) with verified
DOIs and back-links to the guides that cite them; Cited-by line for
Beranek & Mellow from the electroacoustics guide.
docs: speech and electroacoustics didactics, free-field sensitivity diagram and verified references (#190)
* docs: free-field loudspeaker sensitivity setup diagram (IEC 60268-5)
New diagram_loudspeaker_freefield builder in the SVG generator: loudspeaker
on a stand in an anechoic room, amplifier at 2.83 V, dashed reference axis,
measurement microphone at the 1 m reference distance with a drafting
dimension, and the governing sensitivity relations. Four deterministic
variants (EN/ES, light/dark).
* docs: sensitivity-conventions section in the electroacoustics guide
New section on the IEC 60268-4/-5 sensitivity conventions: microphone
sensitivity in mV/Pa and dB re 1 V/Pa with the reference pitfall, and the
loudspeaker characteristic sensitivity with its electrical (2.83 V vs 1 W)
and geometric (1 m reference distance, inverse-distance referral)
normalizations. Embeds the new setup diagram, adds a References section
(Beranek & Mellow) and extends the Standards footer. EN docs, site EN and
site ES.
* docs: MTF intuition and method pitfalls in the speech-transmission guide
Why modulation depth carries intelligibility (envelope valleys, the 7x14
m(F) grid, the effective-SNR mapping), and a direct-vs-indirect subsection
with the pitfalls the standard is explicit about: non-linear and
time-variant channels, level-dependent masking, impulsive and fluctuating
background noise, and the statistical spread of repeated STIPA runs. Adds a
References section (Houtgast & Steeneken 1985). EN docs, site EN and
site ES.
* docs: band-importance meaning and SII vs STI comparison in the SII guide
What the band-importance function means (the French & Steinberg
articulation lineage; intelligibility vs speech power across bands) and a
new SII-or-STI section with a comparison table of questions answered,
inputs, band machinery, blind spots and typical uses. Adds a References
section (French & Steinberg 1947). EN docs, site EN and site ES.
* docs: Speech group in the bibliography
Houtgast & Steeneken (1985) and French & Steinberg (1947) with verified
DOIs and back-links to the guides that cite them; Cited-by line for
Beranek & Mellow from the electroacoustics guide.
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
feat: noise-induced hearing loss (ISO 1999:2013 NIPTS and HTLAN) (#103)
Adds a `phonometry.iso1999` module estimating occupational noise-induced hearing loss, extending the ISO 7029 age-related threshold with a noise component.
* `nipts(l_ex, years, fractile)` — noise-induced permanent threshold shift over 500-6000 Hz: median N50 (clause 6.3.1, Formula 2/3, Table 1) and population fractiles from the half-Gaussian spreads du/dl (clause 6.3.2, Formulae 4-7, Tables 2-3), clamped at zero.
* `htlan(age, sex, l_ex, years, fractile)` — hearing threshold level associated with age and noise, combining the age component (HTLA = ISO 7029) with the NIPTS by H' = H + N - H*N/120 (clause 6.1, Formula 1).
Validated against ISO 1999 Annex D (Tables D.1-D.4, 85-100 dB, 10-40 years): reproduces every tabulated dB value. Conformance 82/82; full suite 1686 passed. Figure + two-lane NIHL diagram (EN/ES, light/dark), repo doc and EN/ES site guides.
feat: noise-induced hearing loss (ISO 1999:2013 NIPTS and HTLAN) (#103)
Adds a `phonometry.iso1999` module estimating occupational noise-induced hearing loss, extending the ISO 7029 age-related threshold with a noise component.
* `nipts(l_ex, years, fractile)` — noise-induced permanent threshold shift over 500-6000 Hz: median N50 (clause 6.3.1, Formula 2/3, Table 1) and population fractiles from the half-Gaussian spreads du/dl (clause 6.3.2, Formulae 4-7, Tables 2-3), clamped at zero.
* `htlan(age, sex, l_ex, years, fractile)` — hearing threshold level associated with age and noise, combining the age component (HTLA = ISO 7029) with the NIPTS by H' = H + N - H*N/120 (clause 6.1, Formula 1).
Validated against ISO 1999 Annex D (Tables D.1-D.4, 85-100 dB, 10-40 years): reproduces every tabulated dB value. Conformance 82/82; full suite 1686 passed. Figure + two-lane NIHL diagram (EN/ES, light/dark), repo doc and EN/ES site guides.
feat: noise-induced hearing loss (ISO 1999:2013 NIPTS and HTLAN) (#103)
Adds a `phonometry.iso1999` module estimating occupational noise-induced hearing loss, extending the ISO 7029 age-related threshold with a noise component.
* `nipts(l_ex, years, fractile)` — noise-induced permanent threshold shift over 500-6000 Hz: median N50 (clause 6.3.1, Formula 2/3, Table 1) and population fractiles from the half-Gaussian spreads du/dl (clause 6.3.2, Formulae 4-7, Tables 2-3), clamped at zero.
* `htlan(age, sex, l_ex, years, fractile)` — hearing threshold level associated with age and noise, combining the age component (HTLA = ISO 7029) with the NIPTS by H' = H + N - H*N/120 (clause 6.1, Formula 1).
Validated against ISO 1999 Annex D (Tables D.1-D.4, 85-100 dB, 10-40 years): reproduces every tabulated dB value. Conformance 82/82; full suite 1686 passed. Figure + two-lane NIHL diagram (EN/ES, light/dark), repo doc and EN/ES site guides.
feat: noise-induced hearing loss (ISO 1999:2013 NIPTS and HTLAN) (#103)
Adds a `phonometry.iso1999` module estimating occupational noise-induced hearing loss, extending the ISO 7029 age-related threshold with a noise component.
* `nipts(l_ex, years, fractile)` — noise-induced permanent threshold shift over 500-6000 Hz: median N50 (clause 6.3.1, Formula 2/3, Table 1) and population fractiles from the half-Gaussian spreads du/dl (clause 6.3.2, Formulae 4-7, Tables 2-3), clamped at zero.
* `htlan(age, sex, l_ex, years, fractile)` — hearing threshold level associated with age and noise, combining the age component (HTLA = ISO 7029) with the NIPTS by H' = H + N - H*N/120 (clause 6.1, Formula 1).
Validated against ISO 1999 Annex D (Tables D.1-D.4, 85-100 dB, 10-40 years): reproduces every tabulated dB value. Conformance 82/82; full suite 1686 passed. Figure + two-lane NIHL diagram (EN/ES, light/dark), repo doc and EN/ES site guides.
NT ACOU 112: impulsive-sound prominence and LAeq adjustment (#105)
* feat: NT ACOU 112 impulsive-sound prominence and LAeq adjustment
Add the Nordtest NT ACOU 112:2002 method for the prominence of
impulsive sounds: the predicted prominence P = 3 lg(OR) + 2 lg(LD)
from each impulse's onset rate and level difference (clause 7,
Formula 1), the graduated adjustment KI = 1.8 (P - 5) dB for P > 5
(clause 8, Formula 2), and the rating level over a reference time
interval (clause 8, Note 1).
New module phonometry.ntacou112 with predicted_prominence,
impulse_adjustment, impulse_prominence (ImpulseProminence result with
.plot()) and rating_level. Conformance report gains an impulsive-sound
domain (2 checks). Adds the impulse-prominence guide (repo + EN/ES
site) with figure and flow diagram.
* refactor: address review feedback on NT ACOU 112
- impulse_prominence: ravel inputs so multi-dimensional arrays flatten
to a 1-D impulse sequence (Gemini)
- figure: use a distinct neutral for the threshold line instead of the
grid color, matching plot_impulse_prominence (Gemini)
- tests: use the shared NTACOU_PROMINENCE / NTACOU_ADJUSTMENT_P10
reference constants instead of hardcoded literals (CodeRabbit)
* refactor: second-pass review polish for NT ACOU 112
- figure: give the impulse markers a distinct light blue (#aec7e8),
matching plot_impulse_prominence, so they read apart from the neutral
threshold line (CodeRabbit)
- tests: split the chained magnitude/approx assertion into two clearer
assertions (CodeRabbit)
NT ACOU 112: impulsive-sound prominence and LAeq adjustment (#105)
* feat: NT ACOU 112 impulsive-sound prominence and LAeq adjustment
Add the Nordtest NT ACOU 112:2002 method for the prominence of
impulsive sounds: the predicted prominence P = 3 lg(OR) + 2 lg(LD)
from each impulse's onset rate and level difference (clause 7,
Formula 1), the graduated adjustment KI = 1.8 (P - 5) dB for P > 5
(clause 8, Formula 2), and the rating level over a reference time
interval (clause 8, Note 1).
New module phonometry.ntacou112 with predicted_prominence,
impulse_adjustment, impulse_prominence (ImpulseProminence result with
.plot()) and rating_level. Conformance report gains an impulsive-sound
domain (2 checks). Adds the impulse-prominence guide (repo + EN/ES
site) with figure and flow diagram.
* refactor: address review feedback on NT ACOU 112
- impulse_prominence: ravel inputs so multi-dimensional arrays flatten
to a 1-D impulse sequence (Gemini)
- figure: use a distinct neutral for the threshold line instead of the
grid color, matching plot_impulse_prominence (Gemini)
- tests: use the shared NTACOU_PROMINENCE / NTACOU_ADJUSTMENT_P10
reference constants instead of hardcoded literals (CodeRabbit)
* refactor: second-pass review polish for NT ACOU 112
- figure: give the impulse markers a distinct light blue (#aec7e8),
matching plot_impulse_prominence, so they read apart from the neutral
threshold line (CodeRabbit)
- tests: split the chained magnitude/approx assertion into two clearer
assertions (CodeRabbit)
Audit pass 7: bilingual EN/ES consistency (#116)
* docs: bilingual EN/ES consistency batch
Audit batch 7 - the Spanish side catches up with the English one:
Content drift: the five per-architecture filter figures join the ES
filter-banks guide; the missing outdoor-propagation card joins the ES
index (7 cards on both sides); the sound-power card says five methods
in both languages (it said three since before ISO 3745/9614-3).
Decimals: the four prose dot-decimals and four code-comment
comma-decimals fixed per convention, and the systematic LaTeX {,}
migration lands - 146 conversions across 16 ES files, every hit
manually reviewed (clause numbers, standard designations, def.:
literals and code identifiers deliberately untouched; zero \d.\d
remain in ES math). The theory band-edge table keeps points (it
mirrors a code snippet's printed output); the why-phonometry report
tables convert to commas (prose).
Terminology unified: fonios, diezmado (including the divergent
multirate alt pair), umbral de audicion, banda atenuada, nivel de
evaluacion (including the rendered NT ACOU 112 ES diagram - the
generator string is fixed and only that SVG pair regenerated),
sharpness (agudeza), and clausula/apartado unified per file majority
(theory: clausula; api: apartado).
Code comments: 22 English comments translated across gum-uncertainty,
hearing-threshold, noise-induced-hearing-loss, room-noise and
occupational-exposure ES (the occupational f-string outputs were
re-executed and match the echoed comments byte-for-byte).
* docs: 'atenuación en banda atenuada' in the ES filter guide
The glossary fix produced a clumsy repetition ('atenuación de banda
atenuada'); the natural phrasing for stopband attenuation is 'en'
(Copilot).
* docs: the sound-power cards enumerate the guide's five routes exactly
The card grouped ISO 9614-2/3 into one item, making 'five routes' read
as four groups (or six standards); it now mirrors the guide's canonical
five-item enumeration, in both languages (CodeRabbit).
Audit pass 7: bilingual EN/ES consistency (#116)
* docs: bilingual EN/ES consistency batch
Audit batch 7 - the Spanish side catches up with the English one:
Content drift: the five per-architecture filter figures join the ES
filter-banks guide; the missing outdoor-propagation card joins the ES
index (7 cards on both sides); the sound-power card says five methods
in both languages (it said three since before ISO 3745/9614-3).
Decimals: the four prose dot-decimals and four code-comment
comma-decimals fixed per convention, and the systematic LaTeX {,}
migration lands - 146 conversions across 16 ES files, every hit
manually reviewed (clause numbers, standard designations, def.:
literals and code identifiers deliberately untouched; zero \d.\d
remain in ES math). The theory band-edge table keeps points (it
mirrors a code snippet's printed output); the why-phonometry report
tables convert to commas (prose).
Terminology unified: fonios, diezmado (including the divergent
multirate alt pair), umbral de audicion, banda atenuada, nivel de
evaluacion (including the rendered NT ACOU 112 ES diagram - the
generator string is fixed and only that SVG pair regenerated),
sharpness (agudeza), and clausula/apartado unified per file majority
(theory: clausula; api: apartado).
Code comments: 22 English comments translated across gum-uncertainty,
hearing-threshold, noise-induced-hearing-loss, room-noise and
occupational-exposure ES (the occupational f-string outputs were
re-executed and match the echoed comments byte-for-byte).
* docs: 'atenuación en banda atenuada' in the ES filter guide
The glossary fix produced a clumsy repetition ('atenuación de banda
atenuada'); the natural phrasing for stopband attenuation is 'en'
(Copilot).
* docs: the sound-power cards enumerate the guide's five routes exactly
The card grouped ISO 9614-2/3 into one item, making 'five routes' read
as four groups (or six standards); it now mirrors the guide's canonical
five-item enumeration, in both languages (CodeRabbit).
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Outdoor sound propagation and occupational noise exposure (ISO 9613-1, ISO 9613-2, ISO 9612) (#89)
* feat: ISO 9613-1 atmospheric sound absorption
Full alpha(f, T, RH, p) model per ISO 9613-1:1993 clauses 6.2-6.4:
oxygen/nitrogen relaxation frequencies, water-vapour molar
concentration from relative humidity, classical + rotational +
vibrational terms. Validated against a 13-point Table 1 grid
(worst deviation 0.39 %, rounding-limited, vs the standard's
stated +/-10 % accuracy) with the exact midband convention of
Eq. (6) Note 5. air_attenuation_m() feeds the ISO 354 m parameter
directly, closing the user-supplied gap. Two conformance checks
added (34/34).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: C1 review nits — test name and comment direction
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: extend ISO 9613-1 Table 1 oracle against the full standard text
The full 37-page ISO 9613-1:1993 text (now in hand) confirms every
implemented constant of Eqs. (3)-(6), the Annex B psychrometric
conversion and the clause 4.2 reference conditions exactly as coded.
Oracle extended from 13 to 23 Table 1 points, adding the 20-50 degC
sub-tables 1(i)-1(p) unavailable in the interim source. Worst
deviation unchanged at 0.385 % (rounding-limited).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9613-2 outdoor sound propagation
Implement the ISO 9613-2:1996 general method for octave-band outdoor sound
attenuation: geometrical divergence (Eq. 7), atmospheric absorption (Eq. 8,
via ISO 9613-1 air_absorption), ground effect (general per-region method of
7.3.1 with the Table 3 a'/b'/c'/d' functions, Eq. 9, plus the alternative
method of 7.3.2, Eq. 10, and the DOmega index Eq. 11), and screening (Eq. 12-18
with the C2/C3 factors, single/double diffraction, Kmet and the 20/25 dB caps).
Adds the Cmet meteorological correction (Eq. 21/22) and the LfT(DW)=Lw+Dc-A
receiver-level composition (Eq. 3/6). Frozen dataclass result exposes the
per-term breakdown (Adiv/Aatm/Agr/Abar). New module, tests and exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9612 occupational noise exposure strategies and uncertainty
Add phonometry.occupational_exposure implementing the three ISO 9612:2009
measurement strategies and the normative Annex C uncertainty budget:
- task_based_exposure (Clause 9): per-task energy average (Eq 7), task
contributions (Eq 8), daily level (Eq 9/10); uncertainty Eq C.3 with
sampling u1a (Eq C.6), duration u1b (Eq C.7) and sensitivity coefficients
c1a (Eq C.4) / c1b (Eq C.5).
- job_based_exposure (Clause 10): effective-day energy average (Eq 11),
daily level (Eq 12); Table 1 minimum-duration check; uncertainty Eq C.9.
- full_day_exposure (Clause 11): whole-day averaging (Eq 11/13) with the
Clause 11.3 three-measurement / 3 dB spread rule.
- Table C.4 (job/full-day c1*u1, bilinear interpolation), Table C.5 (u2),
u3 = 1.0 dB, coverage factor k = 1.65 (one-sided 95 %).
Frozen dataclasses (Task, TaskContribution, ExposureResult), ExposureWarning
advisories for the sampling rules, and exports appended to __init__.
Tests reproduce the Annex D (task), E (job) and F (full-day) worked examples
to the standard's precision, plus closed-form oracles (single 85 dB/8 h task
= 85; equal-level tasks; -3.01 dB per halved duration; k = 1.65) and the
Table C.4 / Table 1 lookups. make check green: 1167 passed, 12 skipped.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 9612 review corrections — Table C.4 digits and Eq C.7 denominator
Two Table C.4 cells verified against the page image at 200 dpi and
corrected (N=6/u1=3.5: 3.4 -> 3.3; N=20/u1=2.0: 0.6 -> 0.5), the test
that echoed the wrong N=6 cell now pins the printed value plus the
corrected N=20 cell. The duration_samples branch of Eq C.7 divides by
J(J-1) like Eq C.6 (standard error of the mean), with a regression test
pinning u1b = 1.0 h for samples (4, 6) h. Module docstring now states
the Lp,Cpeak uncertainty scope cut (Table C.5, NOTE 1).
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: ISO 9613-2 and ISO 9612 conformance checks
Add a new "Outdoor propagation & occupational exposure" conformance domain
with seven closed-form / worked-example checks backed by shared constants in
tests/reference_data.py:
- ISO 9613-2:1996 Eq. (7) geometrical divergence Adiv = 51 dB at 100 m.
- ISO 9613-2:1996 Table 3 ground limit b'(0) = 10,1 -> Agr(250 Hz) = 17,2 dB
(porous ground, hs = hr = 0, dp -> inf).
- ISO 9613-2:1996 clause 7.4 single/double diffraction 20/25 dB caps.
- ISO 9612:2009 Annex D/E/F daily exposure LEX,8h and expanded uncertainty U
(84,3/2,7, 88,1/3,8, 90,1/3,4 dB), the Task objects rebuilt from the shared
input table.
Registry grows 34 -> 41 checks across 8 domains; docs/CONFORMANCE.md
regenerated via make conformance. Registration and reference-data consistency
tests pin the constants to the published values.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: figures for outdoor propagation and occupational exposure
Add four documentation figures (each EN/ES x light/dark) plus a setup diagram:
- air_absorption_alpha: ISO 9613-1 alpha(f) over frequency at four
temperature/humidity combinations (relaxation roll-off, f^2 growth).
- outdoor_attenuation_breakdown: ISO 9613-2 per-term stacked bar (Adiv, Aatm,
Agr, Abar) with the total A, for a 200 m path over porous ground with a 4 m
barrier.
- exposure_uncertainty: ISO 9612 Annex D task contributions with the daily
LEX,8h and the one-sided 95 % upper limit LEX,8h + U.
- diagram_outdoor_geometry: source-barrier-receiver geometry (dss/dsr/z, the
blocked direct ray and the diffracted ray over the top edge).
Spanish translations added to the generate_graphs / generate_diagrams
dictionaries (decimal commas, UNE terminology). Every image visually audited.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: ISO 9613-1/2 outdoor propagation guide and ISO 9612 exposure (EN)
Add the didactic Outdoor Sound Propagation guide (docs/outdoor-propagation.md)
covering ISO 9613-1 atmospheric absorption and the ISO 9613-2 general method
(divergence, atmospheric, ground and barrier terms, the OutdoorAttenuation
breakdown, the alternative 7.3.2 ground method, Cmet), with executed snippets
and honest scope notes (Amisc/reflections not implemented, 7.3.2 not
auto-wired, per-band Cmet a convenience). Extend the Levels guide with the
ISO 9612 occupational-exposure section (task/job/full-day strategies, the
C.6 I(I-1) vs C.12 N-1 asymmetry, Table C.4, k = 1,65, LEX,8h + U upper limit,
Lp,Cpeak uncertainty out of scope), reproducing the Annex D/E/F worked
examples.
Add the matching theory sections, API-reference rows for every new public
name, README feature list + docs table, docs index and CHANGELOG entries.
llms-full.txt / llms.txt regenerated (make llms) with the new page wired into
gen_llms.py. GitHub-safe math throughout; every snippet executed with pasted
outputs.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: outdoor propagation and exposure site twins (EN + ES)
Add the English and Spanish Starlight twins of the new content:
- guides/outdoor-propagation.md (EN + ES) — code-identical snippets to the
docs page; Spanish prose uses UNE terminology ("ponderación temporal"),
decimal commas outside math and code, and the _es figure variants.
- The ISO 9612 section added to guides/levels.md (EN + ES).
- reference/theory.md and reference/api.md rows (EN + ES).
- Landing cards and standards list bumped 34 -> 37 (index.mdx EN + ES);
guides/outdoor-propagation added to the sidebar.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: final branch review — API rows, precision phrasing and ES links
Adds the five missing public-symbol rows (TaskContribution,
table_c4_contribution, minimum_cumulative_duration_hours, COVERAGE_FACTOR,
INSTRUMENT_U2) to the three API references, states the ISO 9613-2 default
atmosphere (20 °C / 70 %, a Table 2 reference atmosphere) in the API rows
and guides, and softens "digit-for-digit" to "the standard's printed
precision" wherever it covered Annex E, whose final level differs only by
the standard's own pre-rounding. ES pages now use the /es/ link prefix
consistently. Code nits from the review: dead arg > 1 guard removed
(z > 0 implies arg >= 3), _with_advisory uses dataclasses.replace, and the
float-keyed _PRIME_BY_BAND gets a safety comment. llms files regenerated.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: validate propagation/exposure inputs and docs lint (PR review)
Addresses the PR #89 bot review:
- Barrier.__post_init__ rejects negative edge distances and a zero
edge_separation (which previously divided by zero in the C3 double-
diffraction factor); Task.__post_init__ rejects empty samples and a
non-positive duration.
- ground_attenuation and barrier_attenuation reject non-positive
frequencies (a zero frequency gave an infinite wavelength / division by
zero); ground_attenuation also checks a positive distance and
non-negative heights. job_based_exposure rejects a non-positive
sample_duration_hours.
- Rewrite the ISO 9613-2 7.3.2 closed form in the guides and API tables so
Markdownlint no longer parses `(...)[...]` as a reversed link (MD011).
- Regression tests for every new guard; docstrings note the new raises.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
Outdoor sound propagation and occupational noise exposure (ISO 9613-1, ISO 9613-2, ISO 9612) (#89)
* feat: ISO 9613-1 atmospheric sound absorption
Full alpha(f, T, RH, p) model per ISO 9613-1:1993 clauses 6.2-6.4:
oxygen/nitrogen relaxation frequencies, water-vapour molar
concentration from relative humidity, classical + rotational +
vibrational terms. Validated against a 13-point Table 1 grid
(worst deviation 0.39 %, rounding-limited, vs the standard's
stated +/-10 % accuracy) with the exact midband convention of
Eq. (6) Note 5. air_attenuation_m() feeds the ISO 354 m parameter
directly, closing the user-supplied gap. Two conformance checks
added (34/34).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: C1 review nits — test name and comment direction
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: extend ISO 9613-1 Table 1 oracle against the full standard text
The full 37-page ISO 9613-1:1993 text (now in hand) confirms every
implemented constant of Eqs. (3)-(6), the Annex B psychrometric
conversion and the clause 4.2 reference conditions exactly as coded.
Oracle extended from 13 to 23 Table 1 points, adding the 20-50 degC
sub-tables 1(i)-1(p) unavailable in the interim source. Worst
deviation unchanged at 0.385 % (rounding-limited).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9613-2 outdoor sound propagation
Implement the ISO 9613-2:1996 general method for octave-band outdoor sound
attenuation: geometrical divergence (Eq. 7), atmospheric absorption (Eq. 8,
via ISO 9613-1 air_absorption), ground effect (general per-region method of
7.3.1 with the Table 3 a'/b'/c'/d' functions, Eq. 9, plus the alternative
method of 7.3.2, Eq. 10, and the DOmega index Eq. 11), and screening (Eq. 12-18
with the C2/C3 factors, single/double diffraction, Kmet and the 20/25 dB caps).
Adds the Cmet meteorological correction (Eq. 21/22) and the LfT(DW)=Lw+Dc-A
receiver-level composition (Eq. 3/6). Frozen dataclass result exposes the
per-term breakdown (Adiv/Aatm/Agr/Abar). New module, tests and exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9612 occupational noise exposure strategies and uncertainty
Add phonometry.occupational_exposure implementing the three ISO 9612:2009
measurement strategies and the normative Annex C uncertainty budget:
- task_based_exposure (Clause 9): per-task energy average (Eq 7), task
contributions (Eq 8), daily level (Eq 9/10); uncertainty Eq C.3 with
sampling u1a (Eq C.6), duration u1b (Eq C.7) and sensitivity coefficients
c1a (Eq C.4) / c1b (Eq C.5).
- job_based_exposure (Clause 10): effective-day energy average (Eq 11),
daily level (Eq 12); Table 1 minimum-duration check; uncertainty Eq C.9.
- full_day_exposure (Clause 11): whole-day averaging (Eq 11/13) with the
Clause 11.3 three-measurement / 3 dB spread rule.
- Table C.4 (job/full-day c1*u1, bilinear interpolation), Table C.5 (u2),
u3 = 1.0 dB, coverage factor k = 1.65 (one-sided 95 %).
Frozen dataclasses (Task, TaskContribution, ExposureResult), ExposureWarning
advisories for the sampling rules, and exports appended to __init__.
Tests reproduce the Annex D (task), E (job) and F (full-day) worked examples
to the standard's precision, plus closed-form oracles (single 85 dB/8 h task
= 85; equal-level tasks; -3.01 dB per halved duration; k = 1.65) and the
Table C.4 / Table 1 lookups. make check green: 1167 passed, 12 skipped.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 9612 review corrections — Table C.4 digits and Eq C.7 denominator
Two Table C.4 cells verified against the page image at 200 dpi and
corrected (N=6/u1=3.5: 3.4 -> 3.3; N=20/u1=2.0: 0.6 -> 0.5), the test
that echoed the wrong N=6 cell now pins the printed value plus the
corrected N=20 cell. The duration_samples branch of Eq C.7 divides by
J(J-1) like Eq C.6 (standard error of the mean), with a regression test
pinning u1b = 1.0 h for samples (4, 6) h. Module docstring now states
the Lp,Cpeak uncertainty scope cut (Table C.5, NOTE 1).
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: ISO 9613-2 and ISO 9612 conformance checks
Add a new "Outdoor propagation & occupational exposure" conformance domain
with seven closed-form / worked-example checks backed by shared constants in
tests/reference_data.py:
- ISO 9613-2:1996 Eq. (7) geometrical divergence Adiv = 51 dB at 100 m.
- ISO 9613-2:1996 Table 3 ground limit b'(0) = 10,1 -> Agr(250 Hz) = 17,2 dB
(porous ground, hs = hr = 0, dp -> inf).
- ISO 9613-2:1996 clause 7.4 single/double diffraction 20/25 dB caps.
- ISO 9612:2009 Annex D/E/F daily exposure LEX,8h and expanded uncertainty U
(84,3/2,7, 88,1/3,8, 90,1/3,4 dB), the Task objects rebuilt from the shared
input table.
Registry grows 34 -> 41 checks across 8 domains; docs/CONFORMANCE.md
regenerated via make conformance. Registration and reference-data consistency
tests pin the constants to the published values.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: figures for outdoor propagation and occupational exposure
Add four documentation figures (each EN/ES x light/dark) plus a setup diagram:
- air_absorption_alpha: ISO 9613-1 alpha(f) over frequency at four
temperature/humidity combinations (relaxation roll-off, f^2 growth).
- outdoor_attenuation_breakdown: ISO 9613-2 per-term stacked bar (Adiv, Aatm,
Agr, Abar) with the total A, for a 200 m path over porous ground with a 4 m
barrier.
- exposure_uncertainty: ISO 9612 Annex D task contributions with the daily
LEX,8h and the one-sided 95 % upper limit LEX,8h + U.
- diagram_outdoor_geometry: source-barrier-receiver geometry (dss/dsr/z, the
blocked direct ray and the diffracted ray over the top edge).
Spanish translations added to the generate_graphs / generate_diagrams
dictionaries (decimal commas, UNE terminology). Every image visually audited.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: ISO 9613-1/2 outdoor propagation guide and ISO 9612 exposure (EN)
Add the didactic Outdoor Sound Propagation guide (docs/outdoor-propagation.md)
covering ISO 9613-1 atmospheric absorption and the ISO 9613-2 general method
(divergence, atmospheric, ground and barrier terms, the OutdoorAttenuation
breakdown, the alternative 7.3.2 ground method, Cmet), with executed snippets
and honest scope notes (Amisc/reflections not implemented, 7.3.2 not
auto-wired, per-band Cmet a convenience). Extend the Levels guide with the
ISO 9612 occupational-exposure section (task/job/full-day strategies, the
C.6 I(I-1) vs C.12 N-1 asymmetry, Table C.4, k = 1,65, LEX,8h + U upper limit,
Lp,Cpeak uncertainty out of scope), reproducing the Annex D/E/F worked
examples.
Add the matching theory sections, API-reference rows for every new public
name, README feature list + docs table, docs index and CHANGELOG entries.
llms-full.txt / llms.txt regenerated (make llms) with the new page wired into
gen_llms.py. GitHub-safe math throughout; every snippet executed with pasted
outputs.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: outdoor propagation and exposure site twins (EN + ES)
Add the English and Spanish Starlight twins of the new content:
- guides/outdoor-propagation.md (EN + ES) — code-identical snippets to the
docs page; Spanish prose uses UNE terminology ("ponderación temporal"),
decimal commas outside math and code, and the _es figure variants.
- The ISO 9612 section added to guides/levels.md (EN + ES).
- reference/theory.md and reference/api.md rows (EN + ES).
- Landing cards and standards list bumped 34 -> 37 (index.mdx EN + ES);
guides/outdoor-propagation added to the sidebar.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: final branch review — API rows, precision phrasing and ES links
Adds the five missing public-symbol rows (TaskContribution,
table_c4_contribution, minimum_cumulative_duration_hours, COVERAGE_FACTOR,
INSTRUMENT_U2) to the three API references, states the ISO 9613-2 default
atmosphere (20 °C / 70 %, a Table 2 reference atmosphere) in the API rows
and guides, and softens "digit-for-digit" to "the standard's printed
precision" wherever it covered Annex E, whose final level differs only by
the standard's own pre-rounding. ES pages now use the /es/ link prefix
consistently. Code nits from the review: dead arg > 1 guard removed
(z > 0 implies arg >= 3), _with_advisory uses dataclasses.replace, and the
float-keyed _PRIME_BY_BAND gets a safety comment. llms files regenerated.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: validate propagation/exposure inputs and docs lint (PR review)
Addresses the PR #89 bot review:
- Barrier.__post_init__ rejects negative edge distances and a zero
edge_separation (which previously divided by zero in the C3 double-
diffraction factor); Task.__post_init__ rejects empty samples and a
non-positive duration.
- ground_attenuation and barrier_attenuation reject non-positive
frequencies (a zero frequency gave an infinite wavelength / division by
zero); ground_attenuation also checks a positive distance and
non-negative heights. job_based_exposure rejects a non-positive
sample_duration_hours.
- Rewrite the ISO 9613-2 7.3.2 closed form in the guides and API tables so
Markdownlint no longer parses `(...)[...]` as a reversed link (MD011).
- Regression tests for every new guard; docstrings note the new raises.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
Outdoor sound propagation and occupational noise exposure (ISO 9613-1, ISO 9613-2, ISO 9612) (#89)
* feat: ISO 9613-1 atmospheric sound absorption
Full alpha(f, T, RH, p) model per ISO 9613-1:1993 clauses 6.2-6.4:
oxygen/nitrogen relaxation frequencies, water-vapour molar
concentration from relative humidity, classical + rotational +
vibrational terms. Validated against a 13-point Table 1 grid
(worst deviation 0.39 %, rounding-limited, vs the standard's
stated +/-10 % accuracy) with the exact midband convention of
Eq. (6) Note 5. air_attenuation_m() feeds the ISO 354 m parameter
directly, closing the user-supplied gap. Two conformance checks
added (34/34).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: C1 review nits — test name and comment direction
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: extend ISO 9613-1 Table 1 oracle against the full standard text
The full 37-page ISO 9613-1:1993 text (now in hand) confirms every
implemented constant of Eqs. (3)-(6), the Annex B psychrometric
conversion and the clause 4.2 reference conditions exactly as coded.
Oracle extended from 13 to 23 Table 1 points, adding the 20-50 degC
sub-tables 1(i)-1(p) unavailable in the interim source. Worst
deviation unchanged at 0.385 % (rounding-limited).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9613-2 outdoor sound propagation
Implement the ISO 9613-2:1996 general method for octave-band outdoor sound
attenuation: geometrical divergence (Eq. 7), atmospheric absorption (Eq. 8,
via ISO 9613-1 air_absorption), ground effect (general per-region method of
7.3.1 with the Table 3 a'/b'/c'/d' functions, Eq. 9, plus the alternative
method of 7.3.2, Eq. 10, and the DOmega index Eq. 11), and screening (Eq. 12-18
with the C2/C3 factors, single/double diffraction, Kmet and the 20/25 dB caps).
Adds the Cmet meteorological correction (Eq. 21/22) and the LfT(DW)=Lw+Dc-A
receiver-level composition (Eq. 3/6). Frozen dataclass result exposes the
per-term breakdown (Adiv/Aatm/Agr/Abar). New module, tests and exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9612 occupational noise exposure strategies and uncertainty
Add phonometry.occupational_exposure implementing the three ISO 9612:2009
measurement strategies and the normative Annex C uncertainty budget:
- task_based_exposure (Clause 9): per-task energy average (Eq 7), task
contributions (Eq 8), daily level (Eq 9/10); uncertainty Eq C.3 with
sampling u1a (Eq C.6), duration u1b (Eq C.7) and sensitivity coefficients
c1a (Eq C.4) / c1b (Eq C.5).
- job_based_exposure (Clause 10): effective-day energy average (Eq 11),
daily level (Eq 12); Table 1 minimum-duration check; uncertainty Eq C.9.
- full_day_exposure (Clause 11): whole-day averaging (Eq 11/13) with the
Clause 11.3 three-measurement / 3 dB spread rule.
- Table C.4 (job/full-day c1*u1, bilinear interpolation), Table C.5 (u2),
u3 = 1.0 dB, coverage factor k = 1.65 (one-sided 95 %).
Frozen dataclasses (Task, TaskContribution, ExposureResult), ExposureWarning
advisories for the sampling rules, and exports appended to __init__.
Tests reproduce the Annex D (task), E (job) and F (full-day) worked examples
to the standard's precision, plus closed-form oracles (single 85 dB/8 h task
= 85; equal-level tasks; -3.01 dB per halved duration; k = 1.65) and the
Table C.4 / Table 1 lookups. make check green: 1167 passed, 12 skipped.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 9612 review corrections — Table C.4 digits and Eq C.7 denominator
Two Table C.4 cells verified against the page image at 200 dpi and
corrected (N=6/u1=3.5: 3.4 -> 3.3; N=20/u1=2.0: 0.6 -> 0.5), the test
that echoed the wrong N=6 cell now pins the printed value plus the
corrected N=20 cell. The duration_samples branch of Eq C.7 divides by
J(J-1) like Eq C.6 (standard error of the mean), with a regression test
pinning u1b = 1.0 h for samples (4, 6) h. Module docstring now states
the Lp,Cpeak uncertainty scope cut (Table C.5, NOTE 1).
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: ISO 9613-2 and ISO 9612 conformance checks
Add a new "Outdoor propagation & occupational exposure" conformance domain
with seven closed-form / worked-example checks backed by shared constants in
tests/reference_data.py:
- ISO 9613-2:1996 Eq. (7) geometrical divergence Adiv = 51 dB at 100 m.
- ISO 9613-2:1996 Table 3 ground limit b'(0) = 10,1 -> Agr(250 Hz) = 17,2 dB
(porous ground, hs = hr = 0, dp -> inf).
- ISO 9613-2:1996 clause 7.4 single/double diffraction 20/25 dB caps.
- ISO 9612:2009 Annex D/E/F daily exposure LEX,8h and expanded uncertainty U
(84,3/2,7, 88,1/3,8, 90,1/3,4 dB), the Task objects rebuilt from the shared
input table.
Registry grows 34 -> 41 checks across 8 domains; docs/CONFORMANCE.md
regenerated via make conformance. Registration and reference-data consistency
tests pin the constants to the published values.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: figures for outdoor propagation and occupational exposure
Add four documentation figures (each EN/ES x light/dark) plus a setup diagram:
- air_absorption_alpha: ISO 9613-1 alpha(f) over frequency at four
temperature/humidity combinations (relaxation roll-off, f^2 growth).
- outdoor_attenuation_breakdown: ISO 9613-2 per-term stacked bar (Adiv, Aatm,
Agr, Abar) with the total A, for a 200 m path over porous ground with a 4 m
barrier.
- exposure_uncertainty: ISO 9612 Annex D task contributions with the daily
LEX,8h and the one-sided 95 % upper limit LEX,8h + U.
- diagram_outdoor_geometry: source-barrier-receiver geometry (dss/dsr/z, the
blocked direct ray and the diffracted ray over the top edge).
Spanish translations added to the generate_graphs / generate_diagrams
dictionaries (decimal commas, UNE terminology). Every image visually audited.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: ISO 9613-1/2 outdoor propagation guide and ISO 9612 exposure (EN)
Add the didactic Outdoor Sound Propagation guide (docs/outdoor-propagation.md)
covering ISO 9613-1 atmospheric absorption and the ISO 9613-2 general method
(divergence, atmospheric, ground and barrier terms, the OutdoorAttenuation
breakdown, the alternative 7.3.2 ground method, Cmet), with executed snippets
and honest scope notes (Amisc/reflections not implemented, 7.3.2 not
auto-wired, per-band Cmet a convenience). Extend the Levels guide with the
ISO 9612 occupational-exposure section (task/job/full-day strategies, the
C.6 I(I-1) vs C.12 N-1 asymmetry, Table C.4, k = 1,65, LEX,8h + U upper limit,
Lp,Cpeak uncertainty out of scope), reproducing the Annex D/E/F worked
examples.
Add the matching theory sections, API-reference rows for every new public
name, README feature list + docs table, docs index and CHANGELOG entries.
llms-full.txt / llms.txt regenerated (make llms) with the new page wired into
gen_llms.py. GitHub-safe math throughout; every snippet executed with pasted
outputs.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: outdoor propagation and exposure site twins (EN + ES)
Add the English and Spanish Starlight twins of the new content:
- guides/outdoor-propagation.md (EN + ES) — code-identical snippets to the
docs page; Spanish prose uses UNE terminology ("ponderación temporal"),
decimal commas outside math and code, and the _es figure variants.
- The ISO 9612 section added to guides/levels.md (EN + ES).
- reference/theory.md and reference/api.md rows (EN + ES).
- Landing cards and standards list bumped 34 -> 37 (index.mdx EN + ES);
guides/outdoor-propagation added to the sidebar.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: final branch review — API rows, precision phrasing and ES links
Adds the five missing public-symbol rows (TaskContribution,
table_c4_contribution, minimum_cumulative_duration_hours, COVERAGE_FACTOR,
INSTRUMENT_U2) to the three API references, states the ISO 9613-2 default
atmosphere (20 °C / 70 %, a Table 2 reference atmosphere) in the API rows
and guides, and softens "digit-for-digit" to "the standard's printed
precision" wherever it covered Annex E, whose final level differs only by
the standard's own pre-rounding. ES pages now use the /es/ link prefix
consistently. Code nits from the review: dead arg > 1 guard removed
(z > 0 implies arg >= 3), _with_advisory uses dataclasses.replace, and the
float-keyed _PRIME_BY_BAND gets a safety comment. llms files regenerated.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: validate propagation/exposure inputs and docs lint (PR review)
Addresses the PR #89 bot review:
- Barrier.__post_init__ rejects negative edge distances and a zero
edge_separation (which previously divided by zero in the C3 double-
diffraction factor); Task.__post_init__ rejects empty samples and a
non-positive duration.
- ground_attenuation and barrier_attenuation reject non-positive
frequencies (a zero frequency gave an infinite wavelength / division by
zero); ground_attenuation also checks a positive distance and
non-negative heights. job_based_exposure rejects a non-positive
sample_duration_hours.
- Rewrite the ISO 9613-2 7.3.2 closed form in the guides and API tables so
Markdownlint no longer parses `(...)[...]` as a reversed link (MD011).
- Regression tests for every new guard; docstrings note the new raises.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
Outdoor sound propagation and occupational noise exposure (ISO 9613-1, ISO 9613-2, ISO 9612) (#89)
* feat: ISO 9613-1 atmospheric sound absorption
Full alpha(f, T, RH, p) model per ISO 9613-1:1993 clauses 6.2-6.4:
oxygen/nitrogen relaxation frequencies, water-vapour molar
concentration from relative humidity, classical + rotational +
vibrational terms. Validated against a 13-point Table 1 grid
(worst deviation 0.39 %, rounding-limited, vs the standard's
stated +/-10 % accuracy) with the exact midband convention of
Eq. (6) Note 5. air_attenuation_m() feeds the ISO 354 m parameter
directly, closing the user-supplied gap. Two conformance checks
added (34/34).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* refactor: C1 review nits — test name and comment direction
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: extend ISO 9613-1 Table 1 oracle against the full standard text
The full 37-page ISO 9613-1:1993 text (now in hand) confirms every
implemented constant of Eqs. (3)-(6), the Annex B psychrometric
conversion and the clause 4.2 reference conditions exactly as coded.
Oracle extended from 13 to 23 Table 1 points, adding the 20-50 degC
sub-tables 1(i)-1(p) unavailable in the interim source. Worst
deviation unchanged at 0.385 % (rounding-limited).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9613-2 outdoor sound propagation
Implement the ISO 9613-2:1996 general method for octave-band outdoor sound
attenuation: geometrical divergence (Eq. 7), atmospheric absorption (Eq. 8,
via ISO 9613-1 air_absorption), ground effect (general per-region method of
7.3.1 with the Table 3 a'/b'/c'/d' functions, Eq. 9, plus the alternative
method of 7.3.2, Eq. 10, and the DOmega index Eq. 11), and screening (Eq. 12-18
with the C2/C3 factors, single/double diffraction, Kmet and the 20/25 dB caps).
Adds the Cmet meteorological correction (Eq. 21/22) and the LfT(DW)=Lw+Dc-A
receiver-level composition (Eq. 3/6). Frozen dataclass result exposes the
per-term breakdown (Adiv/Aatm/Agr/Abar). New module, tests and exports.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9612 occupational noise exposure strategies and uncertainty
Add phonometry.occupational_exposure implementing the three ISO 9612:2009
measurement strategies and the normative Annex C uncertainty budget:
- task_based_exposure (Clause 9): per-task energy average (Eq 7), task
contributions (Eq 8), daily level (Eq 9/10); uncertainty Eq C.3 with
sampling u1a (Eq C.6), duration u1b (Eq C.7) and sensitivity coefficients
c1a (Eq C.4) / c1b (Eq C.5).
- job_based_exposure (Clause 10): effective-day energy average (Eq 11),
daily level (Eq 12); Table 1 minimum-duration check; uncertainty Eq C.9.
- full_day_exposure (Clause 11): whole-day averaging (Eq 11/13) with the
Clause 11.3 three-measurement / 3 dB spread rule.
- Table C.4 (job/full-day c1*u1, bilinear interpolation), Table C.5 (u2),
u3 = 1.0 dB, coverage factor k = 1.65 (one-sided 95 %).
Frozen dataclasses (Task, TaskContribution, ExposureResult), ExposureWarning
advisories for the sampling rules, and exports appended to __init__.
Tests reproduce the Annex D (task), E (job) and F (full-day) worked examples
to the standard's precision, plus closed-form oracles (single 85 dB/8 h task
= 85; equal-level tasks; -3.01 dB per halved duration; k = 1.65) and the
Table C.4 / Table 1 lookups. make check green: 1167 passed, 12 skipped.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 9612 review corrections — Table C.4 digits and Eq C.7 denominator
Two Table C.4 cells verified against the page image at 200 dpi and
corrected (N=6/u1=3.5: 3.4 -> 3.3; N=20/u1=2.0: 0.6 -> 0.5), the test
that echoed the wrong N=6 cell now pins the printed value plus the
corrected N=20 cell. The duration_samples branch of Eq C.7 divides by
J(J-1) like Eq C.6 (standard error of the mean), with a regression test
pinning u1b = 1.0 h for samples (4, 6) h. Module docstring now states
the Lp,Cpeak uncertainty scope cut (Table C.5, NOTE 1).
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: ISO 9613-2 and ISO 9612 conformance checks
Add a new "Outdoor propagation & occupational exposure" conformance domain
with seven closed-form / worked-example checks backed by shared constants in
tests/reference_data.py:
- ISO 9613-2:1996 Eq. (7) geometrical divergence Adiv = 51 dB at 100 m.
- ISO 9613-2:1996 Table 3 ground limit b'(0) = 10,1 -> Agr(250 Hz) = 17,2 dB
(porous ground, hs = hr = 0, dp -> inf).
- ISO 9613-2:1996 clause 7.4 single/double diffraction 20/25 dB caps.
- ISO 9612:2009 Annex D/E/F daily exposure LEX,8h and expanded uncertainty U
(84,3/2,7, 88,1/3,8, 90,1/3,4 dB), the Task objects rebuilt from the shared
input table.
Registry grows 34 -> 41 checks across 8 domains; docs/CONFORMANCE.md
regenerated via make conformance. Registration and reference-data consistency
tests pin the constants to the published values.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: figures for outdoor propagation and occupational exposure
Add four documentation figures (each EN/ES x light/dark) plus a setup diagram:
- air_absorption_alpha: ISO 9613-1 alpha(f) over frequency at four
temperature/humidity combinations (relaxation roll-off, f^2 growth).
- outdoor_attenuation_breakdown: ISO 9613-2 per-term stacked bar (Adiv, Aatm,
Agr, Abar) with the total A, for a 200 m path over porous ground with a 4 m
barrier.
- exposure_uncertainty: ISO 9612 Annex D task contributions with the daily
LEX,8h and the one-sided 95 % upper limit LEX,8h + U.
- diagram_outdoor_geometry: source-barrier-receiver geometry (dss/dsr/z, the
blocked direct ray and the diffracted ray over the top edge).
Spanish translations added to the generate_graphs / generate_diagrams
dictionaries (decimal commas, UNE terminology). Every image visually audited.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: ISO 9613-1/2 outdoor propagation guide and ISO 9612 exposure (EN)
Add the didactic Outdoor Sound Propagation guide (docs/outdoor-propagation.md)
covering ISO 9613-1 atmospheric absorption and the ISO 9613-2 general method
(divergence, atmospheric, ground and barrier terms, the OutdoorAttenuation
breakdown, the alternative 7.3.2 ground method, Cmet), with executed snippets
and honest scope notes (Amisc/reflections not implemented, 7.3.2 not
auto-wired, per-band Cmet a convenience). Extend the Levels guide with the
ISO 9612 occupational-exposure section (task/job/full-day strategies, the
C.6 I(I-1) vs C.12 N-1 asymmetry, Table C.4, k = 1,65, LEX,8h + U upper limit,
Lp,Cpeak uncertainty out of scope), reproducing the Annex D/E/F worked
examples.
Add the matching theory sections, API-reference rows for every new public
name, README feature list + docs table, docs index and CHANGELOG entries.
llms-full.txt / llms.txt regenerated (make llms) with the new page wired into
gen_llms.py. GitHub-safe math throughout; every snippet executed with pasted
outputs.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* docs: outdoor propagation and exposure site twins (EN + ES)
Add the English and Spanish Starlight twins of the new content:
- guides/outdoor-propagation.md (EN + ES) — code-identical snippets to the
docs page; Spanish prose uses UNE terminology ("ponderación temporal"),
decimal commas outside math and code, and the _es figure variants.
- The ISO 9612 section added to guides/levels.md (EN + ES).
- reference/theory.md and reference/api.md rows (EN + ES).
- Landing cards and standards list bumped 34 -> 37 (index.mdx EN + ES);
guides/outdoor-propagation added to the sidebar.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: final branch review — API rows, precision phrasing and ES links
Adds the five missing public-symbol rows (TaskContribution,
table_c4_contribution, minimum_cumulative_duration_hours, COVERAGE_FACTOR,
INSTRUMENT_U2) to the three API references, states the ISO 9613-2 default
atmosphere (20 °C / 70 %, a Table 2 reference atmosphere) in the API rows
and guides, and softens "digit-for-digit" to "the standard's printed
precision" wherever it covered Annex E, whose final level differs only by
the standard's own pre-rounding. ES pages now use the /es/ link prefix
consistently. Code nits from the review: dead arg > 1 guard removed
(z > 0 implies arg >= 3), _with_advisory uses dataclasses.replace, and the
float-keyed _PRIME_BY_BAND gets a safety comment. llms files regenerated.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: validate propagation/exposure inputs and docs lint (PR review)
Addresses the PR #89 bot review:
- Barrier.__post_init__ rejects negative edge distances and a zero
edge_separation (which previously divided by zero in the C3 double-
diffraction factor); Task.__post_init__ rejects empty samples and a
non-positive duration.
- ground_attenuation and barrier_attenuation reject non-positive
frequencies (a zero frequency gave an infinite wavelength / division by
zero); ground_attenuation also checks a positive distance and
non-negative heights. job_based_exposure rejects a non-positive
sample_duration_hours.
- Rewrite the ISO 9613-2 7.3.2 closed form in the guides and API tables so
Markdownlint no longer parses `(...)[...]` as a reversed link (MD011).
- Regression tests for every new guard; docstrings note the new raises.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: final consistency sweep with titled Standards sections and theory references (#202)
* docs: promote closing Standards paragraphs to titled sections
Every guide's closing standards paragraph becomes a proper heading
(## Standards in English, ## Normas in Spanish) across docs/, the site
guides and their Spanish translations, replacing the horizontal rule and
bold-prefix convention. The bibliography pages now describe the new
convention. Content of every paragraph is unchanged.
* docs: add References sections to the domain theory pages
Each theory page (signal analysis, perception and hearing, rooms and
buildings, environment and transport, vibration) now closes with a
References section in English and Spanish, reusing the verified
bibliography entries with support notes tied to the sections of each
page. No new bibliography entries were needed.
* docs: link the bibliography from getting-started and why-phonometry
Getting-started's next-steps list and the closing paragraph of the
why-phonometry comparison now point to the bibliography, in English and
Spanish.
* docs(es): usar "cámara reverberante" en contextos de ISO 354 e ISO 17497
La sala de ensayo de ISO 354 e ISO 17497-1 pasa a llamarse cámara
reverberante en las guías y páginas de teoría en español y en las
etiquetas de los diagramas afectados (dispersión ISO 17497-1 e
ISO 11654), con las variantes SVG regeneradas de forma determinista.
Los contextos de ISO 3741 conservan "sala reverberante".
* docs(es): ISO 3746 es "método de inspección" en la página de teoría
La página de teoría de entorno y transporte alinea el nombre del método
de ISO 3746 con el título de la norma UNE y con la guía de potencia
sonora, que ya decían inspección.
* fix: cite ISO 389-7:2005, the edition actually implemented
The reference-threshold docstrings, theory pages, curated API table and
conformance labels said ISO 389-7:2006; the implemented edition is
ISO 389-7:2005 (EN ISO 389-7:2006 is its European adoption and keeps its
own year). Generated API pages and the conformance report regenerated.
* docs: shorten the high_accuracy table cell in the weighting guide
The oversampling and G-curve details move from the parameter table to
the high-frequency accuracy section, in English and Spanish; the cell
now fits on one line.
* docs: typeset the underwater-propagation formulas as math
The transmission-loss, sonar-equation, seabed-reflection and Wenz
rule-of-fives expressions move from inline code spans to LaTeX math in
the English and Spanish guides and the docs mirror, matching the rest of
the documentation.
* docs: add References sections to loudness, sound quality and multichannel
The three guides now cite their supporting bibliography entries
(Fastl & Zwicker, Fletcher & Munson, ISO 226, IEC 61260-1 and
IEC 61672-1) with per-page support notes, in English and Spanish, and
the bibliographies' cited-by lists are extended accordingly.
* docs(es): última "sala reverberante" pendiente en contexto ISO 17497-1
La frase partida entre líneas de la guía de dispersión superficial se
había escapado del barrido anterior.
* docs: refresh llms-full.txt from the current docs
The committed copy was last generated before the recent documentation
waves; regenerating picks up the didactic pages added since, the new
Standards and References sections and the ISO 389-7:2005 correction.
* docs(site): align the underwater propagation pages with the richer GitHub mirror
docs: final consistency sweep with titled Standards sections and theory references (#202)
* docs: promote closing Standards paragraphs to titled sections
Every guide's closing standards paragraph becomes a proper heading
(## Standards in English, ## Normas in Spanish) across docs/, the site
guides and their Spanish translations, replacing the horizontal rule and
bold-prefix convention. The bibliography pages now describe the new
convention. Content of every paragraph is unchanged.
* docs: add References sections to the domain theory pages
Each theory page (signal analysis, perception and hearing, rooms and
buildings, environment and transport, vibration) now closes with a
References section in English and Spanish, reusing the verified
bibliography entries with support notes tied to the sections of each
page. No new bibliography entries were needed.
* docs: link the bibliography from getting-started and why-phonometry
Getting-started's next-steps list and the closing paragraph of the
why-phonometry comparison now point to the bibliography, in English and
Spanish.
* docs(es): usar "cámara reverberante" en contextos de ISO 354 e ISO 17497
La sala de ensayo de ISO 354 e ISO 17497-1 pasa a llamarse cámara
reverberante en las guías y páginas de teoría en español y en las
etiquetas de los diagramas afectados (dispersión ISO 17497-1 e
ISO 11654), con las variantes SVG regeneradas de forma determinista.
Los contextos de ISO 3741 conservan "sala reverberante".
* docs(es): ISO 3746 es "método de inspección" en la página de teoría
La página de teoría de entorno y transporte alinea el nombre del método
de ISO 3746 con el título de la norma UNE y con la guía de potencia
sonora, que ya decían inspección.
* fix: cite ISO 389-7:2005, the edition actually implemented
The reference-threshold docstrings, theory pages, curated API table and
conformance labels said ISO 389-7:2006; the implemented edition is
ISO 389-7:2005 (EN ISO 389-7:2006 is its European adoption and keeps its
own year). Generated API pages and the conformance report regenerated.
* docs: shorten the high_accuracy table cell in the weighting guide
The oversampling and G-curve details move from the parameter table to
the high-frequency accuracy section, in English and Spanish; the cell
now fits on one line.
* docs: typeset the underwater-propagation formulas as math
The transmission-loss, sonar-equation, seabed-reflection and Wenz
rule-of-fives expressions move from inline code spans to LaTeX math in
the English and Spanish guides and the docs mirror, matching the rest of
the documentation.
* docs: add References sections to loudness, sound quality and multichannel
The three guides now cite their supporting bibliography entries
(Fastl & Zwicker, Fletcher & Munson, ISO 226, IEC 61260-1 and
IEC 61672-1) with per-page support notes, in English and Spanish, and
the bibliographies' cited-by lists are extended accordingly.
* docs(es): última "sala reverberante" pendiente en contexto ISO 17497-1
La frase partida entre líneas de la guía de dispersión superficial se
había escapado del barrido anterior.
* docs: refresh llms-full.txt from the current docs
The committed copy was last generated before the recent documentation
waves; regenerating picks up the didactic pages added since, the new
Standards and References sections and the ISO 389-7:2005 correction.
* docs(site): align the underwater propagation pages with the richer GitHub mirror
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.
fix: SII disturbance per ANSI S3.5, IEC-exact intermodulation and the AES17 measurement chain (#173)
* fix: SII equivalent disturbance is the clause 5.6 maximum, not an energy sum
ANSI S3.5-1997 clause 5.6 defines the equivalent disturbance spectrum
level Di as the larger of the equivalent masking level Zi and the
equivalent internal noise level Xi'. The module summed the two in energy,
underestimating the SII by up to 0.042 in noise-plus-hearing-loss
conditions (0.1841 vs 0.2185 for normal speech in flat 30 dB noise with a
flat 40 dB loss). The official Hornsby worksheet computes the maximum in
every band and the R CRAN worked example confirms it.
Oracles: quiet-condition SII pinned at the worksheet full precision
(0.99582516666667, abs 1e-6), the disturbance intermediate locked at
5000 Hz (-23.6 dB), a discriminating noise-plus-loss case (0.2185) and
the independent R package Example C.2 (0.8513749). A code comment records
that the level-distortion factor referencing the normal-effort spectrum
for every vocal effort is the standard's own definition.
* test: STIPA direct-method modulation-depth staircase and NIPTS reading notes
The IEC 60268-16:2020 C.3.2 verification signal (Formula C.1, sinusoidal
carriers at the A.6.1 male levels) is synthesized end to end and the
published STI staircase for m = 0.0 to 1.0 (0, 0.18, 0.30, 0.38, 0.44,
0.50, 0.56, 0.62, 0.70, 0.82, 1) is asserted within the published
tolerance of 0.05 through the full stipa() audio path; the m = 0.5 point
also joins the conformance report.
ISO 1999 notes: the sub-10-year NIPTS spread keeps the raw lg(t) reading
(Formulae 6/7 carry no Formula-3 extrapolation provision) and the Annex D
half-integer rounding ambiguity of Table D.4 is recorded next to the
pinned cells.
* fix: IEC-exact intermodulation distortion (14.12.7, 14.12.8, 14.12.10)
modulation_distortion now returns the per-order IEC 60268-3 values: d_m,2
and d_m,3 are the arithmetic sums of the sideband amplitudes referenced to
the output voltage at f2 (14.12.7.2 g-h), bundled with the SMPTE-analyzer
combined RMS as an explicitly labelled convention in a new
ModulationDistortionResult.
difference_frequency_distortion references U_2,ref = 2 U_2,f2 (the sum of
both tone amplitudes) and sums the third-order products arithmetically per
14.12.8.1; the former half-difference search window could swallow the
primary tones (octave-spaced clean tones read d2 = 1.0) or the DC bin, so
product windows are now a few bins wide, capped by the component spacing,
clamped to (0, Nyquist) and forced to zero when they cannot be separated
from a primary tone or DC.
total_difference_frequency_distortion implements 14.12.10.1 directly: only
the two in-band products at f0 -/+ delta, rms-summed over the arithmetic
sum of the tone output voltages, with the standard 8 kHz / 11.95 kHz tones
as defaults.
The conformance entries carry the corrected per-clause labels and exact
values (d_m,2 = 0.16, d_m,3 = 0.08, d_d,2 = 0.03, d_d,3 = 0.04, d_TDFD =
sqrt(0.0013)). The 14.12.9.2 f) print of the DIM denominator (U2 vs the
14.12.9.1 f_s amplitude) is recorded in docs/ERRATA.md with a code comment
at the reference measurement.
* fix: AES17 measurement bandwidth, effective notch Q and the ITU-R 468 weighted THD
thd_plus_noise and sinad now measure both the residual and the total
signal through the AES17 chain (5.2.5 / 6.3.1): a 20 Hz high-pass plus
the standard low-pass at a configurable bandwidth (default 20 kHz),
realised as a brick-wall frequency-domain band per 5.2.10. Out-of-band
noise at high sample rates (+7 dB at fs = 192 kHz) and DC offsets no
longer inflate the result; bandwidth=None keeps the full-Nyquist
measurement.
The standard notch is designed so the APPLIED zero-phase response has the
requested quality factor (AES17 5.2.8 defines Q on the combined response;
filtfilt squares the magnitude, so the single-pass design is sharpened by
sqrt(1 + sqrt(2))). Previously a nominal Q of 2.0 acted as 1.29 and
requests below ~1.87 silently fell outside the AES17 [1.2, 3] range.
weighted_thd defaults to the network IEC 60268-3 14.12.11 actually
requires: the IEC 60268-1 Appendix A curve, i.e. ITU-R BS.468-4 Table 1
(peak +12.2 dB at 6.3 kHz), interpolated per the recommendation's own
log-frequency rule and exposed as itu_r_468_weighting; A and C remain as
labelled options and the 31.5 Hz - 400 Hz fundamental validity range is
documented. THD now raises when no harmonic fits below Nyquist instead of
returning 0, captures shorter than 64 samples are rejected, and the THD/
SINAD docstrings state the 14.12.3.2 R-convention and the derived nature
of SINAD explicitly.
New oracles: clipped-sine Fourier constants, the full-signal DIM
regression recipe (1.536 MHz synthesis, weak polynomial nonlinearity,
FIR decimation to 192 kHz, exact-bin FFT oracle), the H1 input-noise
bias SNR/(1+SNR), the printed ITU-R 468 table values including the AES17
CCIR-RMS cross-check, and the effective-notch-Q validation.
* test: ISO 532-1 Annex B.4 level-ramp oracles and reference-source provenance
The Annex B.4 ramp signals 6-9 join the validation suite: the tone ramps
(250 Hz / 1 kHz / 4 kHz, 30 dB to 80 dB at 5 dB/s over 10 s inside a
10.6 s file) are synthesized from parameters measured on the official
electronic-attachment WAVs and pinned to the workbook Nmax/N5 with
tolerances calibrated against those WAVs (module-on-official-WAV agrees
with the workbook to < 0.01 % on Nmax; the synthesis lands within +0.3 %
/ -0.8 %, pinned at 0.6 % / 2 %). The pink-noise ramp (overall SPL
25.85 + 5t dB per the WAV's Annex B.1 calibration) is pinned at a
realization-honest 10 %.
The sub-1-sone phon conversion (0.0005 offset, 3.0 phon floor, exact
10/lg 2 factor) and the NX percentile ((k-1, k) mean at
k = int((1 - X/100) n)) are now confirmed line by line against the
attachment's Annex A.4 reference program source; the provenance
docstrings record the exact code they match.
* docs: IEC-exact IMD semantics, AES17 bandwidth and ITU-R 468 weighting across guides and reference
The electroacoustics guide (EN and ES) and the API reference describe the
per-order modulation and difference-frequency definitions with their
references and arithmetic sums, the 14.12.10 two-product TDFD with the
standard 8 kHz / 11.95 kHz defaults, the AES17 measurement-bandwidth chain
with its bandwidth escape hatch, the effective notch Q, the ITU-R BS.468-4
default weighting for weighted THD with the 31.5-400 Hz validity range,
the DIM denominator erratum link and the corrected THD/SINAD convention
wording. CHANGELOG records the added API and the fixes; the conformance
report and the distortion figure variants are regenerated.
* docs: the ISO 12354-1:2017 edition repeats the K24 clamp misprint and flips the double-leaf K24 sign
The 2017 edition repeats the impossible '0 <= K24 <= -4 dB' interval of the
2000 print verbatim, and its E.3.5 prints the double-leaf K24 with a plus
where the 2000 edition's formula and its own corroborating Figure E.9 curve
carry a minus; both are recorded in the errata registry and the sign choice
is noted at the implementation.
* docs: the theory pages and SII diagram teach the max-form disturbance
The equivalent disturbance prose in the theory pages and the diagram label
follow the corrected ANSI S3.5 clause 5.6 reading (the larger of masking
and internal noise, not their energy sum), in English and Spanish; the
ISO 532-1 provenance docstrings paraphrase the reference program instead of
quoting it; and the notch-Q compensation note states the bilinear-warp
caveat near Nyquist.
* fix: regenerate the SII figure for the max-form disturbance and analysis follow-ups
The speech-intelligibility figure consumes the corrected clause 5.6
disturbance, so its four variants are regenerated; the 468 weighting's
zero-frequency guard avoids floating-point equality and the exception
tests keep one throwing call per block.
fix: SII disturbance per ANSI S3.5, IEC-exact intermodulation and the AES17 measurement chain (#173)
* fix: SII equivalent disturbance is the clause 5.6 maximum, not an energy sum
ANSI S3.5-1997 clause 5.6 defines the equivalent disturbance spectrum
level Di as the larger of the equivalent masking level Zi and the
equivalent internal noise level Xi'. The module summed the two in energy,
underestimating the SII by up to 0.042 in noise-plus-hearing-loss
conditions (0.1841 vs 0.2185 for normal speech in flat 30 dB noise with a
flat 40 dB loss). The official Hornsby worksheet computes the maximum in
every band and the R CRAN worked example confirms it.
Oracles: quiet-condition SII pinned at the worksheet full precision
(0.99582516666667, abs 1e-6), the disturbance intermediate locked at
5000 Hz (-23.6 dB), a discriminating noise-plus-loss case (0.2185) and
the independent R package Example C.2 (0.8513749). A code comment records
that the level-distortion factor referencing the normal-effort spectrum
for every vocal effort is the standard's own definition.
* test: STIPA direct-method modulation-depth staircase and NIPTS reading notes
The IEC 60268-16:2020 C.3.2 verification signal (Formula C.1, sinusoidal
carriers at the A.6.1 male levels) is synthesized end to end and the
published STI staircase for m = 0.0 to 1.0 (0, 0.18, 0.30, 0.38, 0.44,
0.50, 0.56, 0.62, 0.70, 0.82, 1) is asserted within the published
tolerance of 0.05 through the full stipa() audio path; the m = 0.5 point
also joins the conformance report.
ISO 1999 notes: the sub-10-year NIPTS spread keeps the raw lg(t) reading
(Formulae 6/7 carry no Formula-3 extrapolation provision) and the Annex D
half-integer rounding ambiguity of Table D.4 is recorded next to the
pinned cells.
* fix: IEC-exact intermodulation distortion (14.12.7, 14.12.8, 14.12.10)
modulation_distortion now returns the per-order IEC 60268-3 values: d_m,2
and d_m,3 are the arithmetic sums of the sideband amplitudes referenced to
the output voltage at f2 (14.12.7.2 g-h), bundled with the SMPTE-analyzer
combined RMS as an explicitly labelled convention in a new
ModulationDistortionResult.
difference_frequency_distortion references U_2,ref = 2 U_2,f2 (the sum of
both tone amplitudes) and sums the third-order products arithmetically per
14.12.8.1; the former half-difference search window could swallow the
primary tones (octave-spaced clean tones read d2 = 1.0) or the DC bin, so
product windows are now a few bins wide, capped by the component spacing,
clamped to (0, Nyquist) and forced to zero when they cannot be separated
from a primary tone or DC.
total_difference_frequency_distortion implements 14.12.10.1 directly: only
the two in-band products at f0 -/+ delta, rms-summed over the arithmetic
sum of the tone output voltages, with the standard 8 kHz / 11.95 kHz tones
as defaults.
The conformance entries carry the corrected per-clause labels and exact
values (d_m,2 = 0.16, d_m,3 = 0.08, d_d,2 = 0.03, d_d,3 = 0.04, d_TDFD =
sqrt(0.0013)). The 14.12.9.2 f) print of the DIM denominator (U2 vs the
14.12.9.1 f_s amplitude) is recorded in docs/ERRATA.md with a code comment
at the reference measurement.
* fix: AES17 measurement bandwidth, effective notch Q and the ITU-R 468 weighted THD
thd_plus_noise and sinad now measure both the residual and the total
signal through the AES17 chain (5.2.5 / 6.3.1): a 20 Hz high-pass plus
the standard low-pass at a configurable bandwidth (default 20 kHz),
realised as a brick-wall frequency-domain band per 5.2.10. Out-of-band
noise at high sample rates (+7 dB at fs = 192 kHz) and DC offsets no
longer inflate the result; bandwidth=None keeps the full-Nyquist
measurement.
The standard notch is designed so the APPLIED zero-phase response has the
requested quality factor (AES17 5.2.8 defines Q on the combined response;
filtfilt squares the magnitude, so the single-pass design is sharpened by
sqrt(1 + sqrt(2))). Previously a nominal Q of 2.0 acted as 1.29 and
requests below ~1.87 silently fell outside the AES17 [1.2, 3] range.
weighted_thd defaults to the network IEC 60268-3 14.12.11 actually
requires: the IEC 60268-1 Appendix A curve, i.e. ITU-R BS.468-4 Table 1
(peak +12.2 dB at 6.3 kHz), interpolated per the recommendation's own
log-frequency rule and exposed as itu_r_468_weighting; A and C remain as
labelled options and the 31.5 Hz - 400 Hz fundamental validity range is
documented. THD now raises when no harmonic fits below Nyquist instead of
returning 0, captures shorter than 64 samples are rejected, and the THD/
SINAD docstrings state the 14.12.3.2 R-convention and the derived nature
of SINAD explicitly.
New oracles: clipped-sine Fourier constants, the full-signal DIM
regression recipe (1.536 MHz synthesis, weak polynomial nonlinearity,
FIR decimation to 192 kHz, exact-bin FFT oracle), the H1 input-noise
bias SNR/(1+SNR), the printed ITU-R 468 table values including the AES17
CCIR-RMS cross-check, and the effective-notch-Q validation.
* test: ISO 532-1 Annex B.4 level-ramp oracles and reference-source provenance
The Annex B.4 ramp signals 6-9 join the validation suite: the tone ramps
(250 Hz / 1 kHz / 4 kHz, 30 dB to 80 dB at 5 dB/s over 10 s inside a
10.6 s file) are synthesized from parameters measured on the official
electronic-attachment WAVs and pinned to the workbook Nmax/N5 with
tolerances calibrated against those WAVs (module-on-official-WAV agrees
with the workbook to < 0.01 % on Nmax; the synthesis lands within +0.3 %
/ -0.8 %, pinned at 0.6 % / 2 %). The pink-noise ramp (overall SPL
25.85 + 5t dB per the WAV's Annex B.1 calibration) is pinned at a
realization-honest 10 %.
The sub-1-sone phon conversion (0.0005 offset, 3.0 phon floor, exact
10/lg 2 factor) and the NX percentile ((k-1, k) mean at
k = int((1 - X/100) n)) are now confirmed line by line against the
attachment's Annex A.4 reference program source; the provenance
docstrings record the exact code they match.
* docs: IEC-exact IMD semantics, AES17 bandwidth and ITU-R 468 weighting across guides and reference
The electroacoustics guide (EN and ES) and the API reference describe the
per-order modulation and difference-frequency definitions with their
references and arithmetic sums, the 14.12.10 two-product TDFD with the
standard 8 kHz / 11.95 kHz defaults, the AES17 measurement-bandwidth chain
with its bandwidth escape hatch, the effective notch Q, the ITU-R BS.468-4
default weighting for weighted THD with the 31.5-400 Hz validity range,
the DIM denominator erratum link and the corrected THD/SINAD convention
wording. CHANGELOG records the added API and the fixes; the conformance
report and the distortion figure variants are regenerated.
* docs: the ISO 12354-1:2017 edition repeats the K24 clamp misprint and flips the double-leaf K24 sign
The 2017 edition repeats the impossible '0 <= K24 <= -4 dB' interval of the
2000 print verbatim, and its E.3.5 prints the double-leaf K24 with a plus
where the 2000 edition's formula and its own corroborating Figure E.9 curve
carry a minus; both are recorded in the errata registry and the sign choice
is noted at the implementation.
* docs: the theory pages and SII diagram teach the max-form disturbance
The equivalent disturbance prose in the theory pages and the diagram label
follow the corrected ANSI S3.5 clause 5.6 reading (the larger of masking
and internal noise, not their energy sum), in English and Spanish; the
ISO 532-1 provenance docstrings paraphrase the reference program instead of
quoting it; and the notch-Q compensation note states the bilinear-warp
caveat near Nyquist.
* fix: regenerate the SII figure for the max-form disturbance and analysis follow-ups
The speech-intelligibility figure consumes the corrected clause 5.6
disturbance, so its four variants are regenerated; the 468 weighting's
zero-frequency guard avoids floating-point equality and the exception
tests keep one throwing call per block.
fix: SII disturbance per ANSI S3.5, IEC-exact intermodulation and the AES17 measurement chain (#173)
* fix: SII equivalent disturbance is the clause 5.6 maximum, not an energy sum
ANSI S3.5-1997 clause 5.6 defines the equivalent disturbance spectrum
level Di as the larger of the equivalent masking level Zi and the
equivalent internal noise level Xi'. The module summed the two in energy,
underestimating the SII by up to 0.042 in noise-plus-hearing-loss
conditions (0.1841 vs 0.2185 for normal speech in flat 30 dB noise with a
flat 40 dB loss). The official Hornsby worksheet computes the maximum in
every band and the R CRAN worked example confirms it.
Oracles: quiet-condition SII pinned at the worksheet full precision
(0.99582516666667, abs 1e-6), the disturbance intermediate locked at
5000 Hz (-23.6 dB), a discriminating noise-plus-loss case (0.2185) and
the independent R package Example C.2 (0.8513749). A code comment records
that the level-distortion factor referencing the normal-effort spectrum
for every vocal effort is the standard's own definition.
* test: STIPA direct-method modulation-depth staircase and NIPTS reading notes
The IEC 60268-16:2020 C.3.2 verification signal (Formula C.1, sinusoidal
carriers at the A.6.1 male levels) is synthesized end to end and the
published STI staircase for m = 0.0 to 1.0 (0, 0.18, 0.30, 0.38, 0.44,
0.50, 0.56, 0.62, 0.70, 0.82, 1) is asserted within the published
tolerance of 0.05 through the full stipa() audio path; the m = 0.5 point
also joins the conformance report.
ISO 1999 notes: the sub-10-year NIPTS spread keeps the raw lg(t) reading
(Formulae 6/7 carry no Formula-3 extrapolation provision) and the Annex D
half-integer rounding ambiguity of Table D.4 is recorded next to the
pinned cells.
* fix: IEC-exact intermodulation distortion (14.12.7, 14.12.8, 14.12.10)
modulation_distortion now returns the per-order IEC 60268-3 values: d_m,2
and d_m,3 are the arithmetic sums of the sideband amplitudes referenced to
the output voltage at f2 (14.12.7.2 g-h), bundled with the SMPTE-analyzer
combined RMS as an explicitly labelled convention in a new
ModulationDistortionResult.
difference_frequency_distortion references U_2,ref = 2 U_2,f2 (the sum of
both tone amplitudes) and sums the third-order products arithmetically per
14.12.8.1; the former half-difference search window could swallow the
primary tones (octave-spaced clean tones read d2 = 1.0) or the DC bin, so
product windows are now a few bins wide, capped by the component spacing,
clamped to (0, Nyquist) and forced to zero when they cannot be separated
from a primary tone or DC.
total_difference_frequency_distortion implements 14.12.10.1 directly: only
the two in-band products at f0 -/+ delta, rms-summed over the arithmetic
sum of the tone output voltages, with the standard 8 kHz / 11.95 kHz tones
as defaults.
The conformance entries carry the corrected per-clause labels and exact
values (d_m,2 = 0.16, d_m,3 = 0.08, d_d,2 = 0.03, d_d,3 = 0.04, d_TDFD =
sqrt(0.0013)). The 14.12.9.2 f) print of the DIM denominator (U2 vs the
14.12.9.1 f_s amplitude) is recorded in docs/ERRATA.md with a code comment
at the reference measurement.
* fix: AES17 measurement bandwidth, effective notch Q and the ITU-R 468 weighted THD
thd_plus_noise and sinad now measure both the residual and the total
signal through the AES17 chain (5.2.5 / 6.3.1): a 20 Hz high-pass plus
the standard low-pass at a configurable bandwidth (default 20 kHz),
realised as a brick-wall frequency-domain band per 5.2.10. Out-of-band
noise at high sample rates (+7 dB at fs = 192 kHz) and DC offsets no
longer inflate the result; bandwidth=None keeps the full-Nyquist
measurement.
The standard notch is designed so the APPLIED zero-phase response has the
requested quality factor (AES17 5.2.8 defines Q on the combined response;
filtfilt squares the magnitude, so the single-pass design is sharpened by
sqrt(1 + sqrt(2))). Previously a nominal Q of 2.0 acted as 1.29 and
requests below ~1.87 silently fell outside the AES17 [1.2, 3] range.
weighted_thd defaults to the network IEC 60268-3 14.12.11 actually
requires: the IEC 60268-1 Appendix A curve, i.e. ITU-R BS.468-4 Table 1
(peak +12.2 dB at 6.3 kHz), interpolated per the recommendation's own
log-frequency rule and exposed as itu_r_468_weighting; A and C remain as
labelled options and the 31.5 Hz - 400 Hz fundamental validity range is
documented. THD now raises when no harmonic fits below Nyquist instead of
returning 0, captures shorter than 64 samples are rejected, and the THD/
SINAD docstrings state the 14.12.3.2 R-convention and the derived nature
of SINAD explicitly.
New oracles: clipped-sine Fourier constants, the full-signal DIM
regression recipe (1.536 MHz synthesis, weak polynomial nonlinearity,
FIR decimation to 192 kHz, exact-bin FFT oracle), the H1 input-noise
bias SNR/(1+SNR), the printed ITU-R 468 table values including the AES17
CCIR-RMS cross-check, and the effective-notch-Q validation.
* test: ISO 532-1 Annex B.4 level-ramp oracles and reference-source provenance
The Annex B.4 ramp signals 6-9 join the validation suite: the tone ramps
(250 Hz / 1 kHz / 4 kHz, 30 dB to 80 dB at 5 dB/s over 10 s inside a
10.6 s file) are synthesized from parameters measured on the official
electronic-attachment WAVs and pinned to the workbook Nmax/N5 with
tolerances calibrated against those WAVs (module-on-official-WAV agrees
with the workbook to < 0.01 % on Nmax; the synthesis lands within +0.3 %
/ -0.8 %, pinned at 0.6 % / 2 %). The pink-noise ramp (overall SPL
25.85 + 5t dB per the WAV's Annex B.1 calibration) is pinned at a
realization-honest 10 %.
The sub-1-sone phon conversion (0.0005 offset, 3.0 phon floor, exact
10/lg 2 factor) and the NX percentile ((k-1, k) mean at
k = int((1 - X/100) n)) are now confirmed line by line against the
attachment's Annex A.4 reference program source; the provenance
docstrings record the exact code they match.
* docs: IEC-exact IMD semantics, AES17 bandwidth and ITU-R 468 weighting across guides and reference
The electroacoustics guide (EN and ES) and the API reference describe the
per-order modulation and difference-frequency definitions with their
references and arithmetic sums, the 14.12.10 two-product TDFD with the
standard 8 kHz / 11.95 kHz defaults, the AES17 measurement-bandwidth chain
with its bandwidth escape hatch, the effective notch Q, the ITU-R BS.468-4
default weighting for weighted THD with the 31.5-400 Hz validity range,
the DIM denominator erratum link and the corrected THD/SINAD convention
wording. CHANGELOG records the added API and the fixes; the conformance
report and the distortion figure variants are regenerated.
* docs: the ISO 12354-1:2017 edition repeats the K24 clamp misprint and flips the double-leaf K24 sign
The 2017 edition repeats the impossible '0 <= K24 <= -4 dB' interval of the
2000 print verbatim, and its E.3.5 prints the double-leaf K24 with a plus
where the 2000 edition's formula and its own corroborating Figure E.9 curve
carry a minus; both are recorded in the errata registry and the sign choice
is noted at the implementation.
* docs: the theory pages and SII diagram teach the max-form disturbance
The equivalent disturbance prose in the theory pages and the diagram label
follow the corrected ANSI S3.5 clause 5.6 reading (the larger of masking
and internal noise, not their energy sum), in English and Spanish; the
ISO 532-1 provenance docstrings paraphrase the reference program instead of
quoting it; and the notch-Q compensation note states the bilinear-warp
caveat near Nyquist.
* fix: regenerate the SII figure for the max-form disturbance and analysis follow-ups
The speech-intelligibility figure consumes the corrected clause 5.6
disturbance, so its four variants are regenerated; the 468 weighting's
zero-frequency guard avoids floating-point equality and the exception
tests keep one throwing call per block.
fix: SII disturbance per ANSI S3.5, IEC-exact intermodulation and the AES17 measurement chain (#173)
* fix: SII equivalent disturbance is the clause 5.6 maximum, not an energy sum
ANSI S3.5-1997 clause 5.6 defines the equivalent disturbance spectrum
level Di as the larger of the equivalent masking level Zi and the
equivalent internal noise level Xi'. The module summed the two in energy,
underestimating the SII by up to 0.042 in noise-plus-hearing-loss
conditions (0.1841 vs 0.2185 for normal speech in flat 30 dB noise with a
flat 40 dB loss). The official Hornsby worksheet computes the maximum in
every band and the R CRAN worked example confirms it.
Oracles: quiet-condition SII pinned at the worksheet full precision
(0.99582516666667, abs 1e-6), the disturbance intermediate locked at
5000 Hz (-23.6 dB), a discriminating noise-plus-loss case (0.2185) and
the independent R package Example C.2 (0.8513749). A code comment records
that the level-distortion factor referencing the normal-effort spectrum
for every vocal effort is the standard's own definition.
* test: STIPA direct-method modulation-depth staircase and NIPTS reading notes
The IEC 60268-16:2020 C.3.2 verification signal (Formula C.1, sinusoidal
carriers at the A.6.1 male levels) is synthesized end to end and the
published STI staircase for m = 0.0 to 1.0 (0, 0.18, 0.30, 0.38, 0.44,
0.50, 0.56, 0.62, 0.70, 0.82, 1) is asserted within the published
tolerance of 0.05 through the full stipa() audio path; the m = 0.5 point
also joins the conformance report.
ISO 1999 notes: the sub-10-year NIPTS spread keeps the raw lg(t) reading
(Formulae 6/7 carry no Formula-3 extrapolation provision) and the Annex D
half-integer rounding ambiguity of Table D.4 is recorded next to the
pinned cells.
* fix: IEC-exact intermodulation distortion (14.12.7, 14.12.8, 14.12.10)
modulation_distortion now returns the per-order IEC 60268-3 values: d_m,2
and d_m,3 are the arithmetic sums of the sideband amplitudes referenced to
the output voltage at f2 (14.12.7.2 g-h), bundled with the SMPTE-analyzer
combined RMS as an explicitly labelled convention in a new
ModulationDistortionResult.
difference_frequency_distortion references U_2,ref = 2 U_2,f2 (the sum of
both tone amplitudes) and sums the third-order products arithmetically per
14.12.8.1; the former half-difference search window could swallow the
primary tones (octave-spaced clean tones read d2 = 1.0) or the DC bin, so
product windows are now a few bins wide, capped by the component spacing,
clamped to (0, Nyquist) and forced to zero when they cannot be separated
from a primary tone or DC.
total_difference_frequency_distortion implements 14.12.10.1 directly: only
the two in-band products at f0 -/+ delta, rms-summed over the arithmetic
sum of the tone output voltages, with the standard 8 kHz / 11.95 kHz tones
as defaults.
The conformance entries carry the corrected per-clause labels and exact
values (d_m,2 = 0.16, d_m,3 = 0.08, d_d,2 = 0.03, d_d,3 = 0.04, d_TDFD =
sqrt(0.0013)). The 14.12.9.2 f) print of the DIM denominator (U2 vs the
14.12.9.1 f_s amplitude) is recorded in docs/ERRATA.md with a code comment
at the reference measurement.
* fix: AES17 measurement bandwidth, effective notch Q and the ITU-R 468 weighted THD
thd_plus_noise and sinad now measure both the residual and the total
signal through the AES17 chain (5.2.5 / 6.3.1): a 20 Hz high-pass plus
the standard low-pass at a configurable bandwidth (default 20 kHz),
realised as a brick-wall frequency-domain band per 5.2.10. Out-of-band
noise at high sample rates (+7 dB at fs = 192 kHz) and DC offsets no
longer inflate the result; bandwidth=None keeps the full-Nyquist
measurement.
The standard notch is designed so the APPLIED zero-phase response has the
requested quality factor (AES17 5.2.8 defines Q on the combined response;
filtfilt squares the magnitude, so the single-pass design is sharpened by
sqrt(1 + sqrt(2))). Previously a nominal Q of 2.0 acted as 1.29 and
requests below ~1.87 silently fell outside the AES17 [1.2, 3] range.
weighted_thd defaults to the network IEC 60268-3 14.12.11 actually
requires: the IEC 60268-1 Appendix A curve, i.e. ITU-R BS.468-4 Table 1
(peak +12.2 dB at 6.3 kHz), interpolated per the recommendation's own
log-frequency rule and exposed as itu_r_468_weighting; A and C remain as
labelled options and the 31.5 Hz - 400 Hz fundamental validity range is
documented. THD now raises when no harmonic fits below Nyquist instead of
returning 0, captures shorter than 64 samples are rejected, and the THD/
SINAD docstrings state the 14.12.3.2 R-convention and the derived nature
of SINAD explicitly.
New oracles: clipped-sine Fourier constants, the full-signal DIM
regression recipe (1.536 MHz synthesis, weak polynomial nonlinearity,
FIR decimation to 192 kHz, exact-bin FFT oracle), the H1 input-noise
bias SNR/(1+SNR), the printed ITU-R 468 table values including the AES17
CCIR-RMS cross-check, and the effective-notch-Q validation.
* test: ISO 532-1 Annex B.4 level-ramp oracles and reference-source provenance
The Annex B.4 ramp signals 6-9 join the validation suite: the tone ramps
(250 Hz / 1 kHz / 4 kHz, 30 dB to 80 dB at 5 dB/s over 10 s inside a
10.6 s file) are synthesized from parameters measured on the official
electronic-attachment WAVs and pinned to the workbook Nmax/N5 with
tolerances calibrated against those WAVs (module-on-official-WAV agrees
with the workbook to < 0.01 % on Nmax; the synthesis lands within +0.3 %
/ -0.8 %, pinned at 0.6 % / 2 %). The pink-noise ramp (overall SPL
25.85 + 5t dB per the WAV's Annex B.1 calibration) is pinned at a
realization-honest 10 %.
The sub-1-sone phon conversion (0.0005 offset, 3.0 phon floor, exact
10/lg 2 factor) and the NX percentile ((k-1, k) mean at
k = int((1 - X/100) n)) are now confirmed line by line against the
attachment's Annex A.4 reference program source; the provenance
docstrings record the exact code they match.
* docs: IEC-exact IMD semantics, AES17 bandwidth and ITU-R 468 weighting across guides and reference
The electroacoustics guide (EN and ES) and the API reference describe the
per-order modulation and difference-frequency definitions with their
references and arithmetic sums, the 14.12.10 two-product TDFD with the
standard 8 kHz / 11.95 kHz defaults, the AES17 measurement-bandwidth chain
with its bandwidth escape hatch, the effective notch Q, the ITU-R BS.468-4
default weighting for weighted THD with the 31.5-400 Hz validity range,
the DIM denominator erratum link and the corrected THD/SINAD convention
wording. CHANGELOG records the added API and the fixes; the conformance
report and the distortion figure variants are regenerated.
* docs: the ISO 12354-1:2017 edition repeats the K24 clamp misprint and flips the double-leaf K24 sign
The 2017 edition repeats the impossible '0 <= K24 <= -4 dB' interval of the
2000 print verbatim, and its E.3.5 prints the double-leaf K24 with a plus
where the 2000 edition's formula and its own corroborating Figure E.9 curve
carry a minus; both are recorded in the errata registry and the sign choice
is noted at the implementation.
* docs: the theory pages and SII diagram teach the max-form disturbance
The equivalent disturbance prose in the theory pages and the diagram label
follow the corrected ANSI S3.5 clause 5.6 reading (the larger of masking
and internal noise, not their energy sum), in English and Spanish; the
ISO 532-1 provenance docstrings paraphrase the reference program instead of
quoting it; and the notch-Q compensation note states the bilinear-warp
caveat near Nyquist.
* fix: regenerate the SII figure for the max-form disturbance and analysis follow-ups
The speech-intelligibility figure consumes the corrected clause 5.6
disturbance, so its four variants are regenerated; the 468 weighting's
zero-frequency guard avoids floating-point equality and the exception
tests keep one throwing call per block.
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Psychoacoustics, speech intelligibility and sound intensity (ISO 532-1, DIN 45692, IEC 60268-16, IEC 61043) (#80)
* test: ISO 532-1 Annex B expected-value fixtures
Expected N (stationary, with the Annex tolerances) and Nmax/N5
(time-varying, 5% tolerance) for all 25 normative test signals,
extracted from the results workbooks of the freely downloadable
ISO 532-1:2017 electronic attachment, plus the Test signal 1
third-octave input levels.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: Zwicker loudness per ISO 532-1:2017 (stationary and time-varying)
Clean-room Python port of the normative Annex A.4 reference
implementation: all twelve numeric tables (A.1-A.9) verified
digit-exact against the C source in _zwicker_data.py, the Table A.1/A.2
third-octave filterbank, the level-dependent weighting, critical-band
and core-loudness stages, the exact f_nl nonlinear temporal-decay state
machine, temporal weighting and the 500 Hz loudness-vs-time trace with
Nmax/N5/N10. API: loudness_zwicker(x, fs, field=, stationary=) and
loudness_zwicker_from_spectrum(levels, field=) returning a frozen
ZwickerLoudness dataclass.
Conformance (Annex B, from the freely downloadable ISO electronic
attachment): Test signal 1 stationary spectrum matches the published N
to all printed digits (83.2957 sone); regenerated B.3 tones sit inside
the workbook tolerance intervals; the B.4 tone-pulse WAVs (included,
small) must keep >=99% of the N(t) trace inside the per-sample
normative tolerance band - the workbook header N5 values are not
reproducible from their own published traces and are documented as not
asserted. B.5 technical recordings run when ISO532_1_TESTDATA points
at the attachment.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: sharpness per DIN 45692:2009 (acum)
sharpness_din(x, fs, field=, method=) and
sharpness_din_from_specific(specific) implement Equation (1) - the
g(z)-weighted first moment of the ISO 532-1 specific-loudness pattern -
with the normalization constant k derived numerically from the clause 6
standard test signal (critical-band-wide 920-1080 Hz noise at 60 dB ->
exactly 1.00 acum; the derived k = 0.108 sits inside the normative
0.105 <= k < 0.115 window). The informative Annex B variants of Aures
and von Bismarck are selectable. Conformance tests: reference identity,
k range, and Table A.2 targets at four centre frequencies using
critical-band noises equalized to 4 sone (Tabelle A.1 band edges),
within the clause 6 tolerance of 5 % or 0.05 acum.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: annotate Aures weighting return for strict mypy
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: robust short-signal handling and consistent peak pattern in Zwicker port
Findings surfaced by review bots on an accidental early diff: (1) inputs
shorter than one 500 Hz output sample crashed on an empty percentile
buffer - the minimum-length validation now requires a full output step;
(2) the returned specific pattern was picked with the un-decimated
argmax while Nmax/N5/N10 come from the decimated trace - both now use
the same decimated instant (regression tests added; note the pattern
integral only equals Nmax for steady signals, since N(t) is temporally
weighted).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: STI/STIPA (IEC 60268-16 Ed. 5) and p-p sound intensity (IEC 61043 + ISO 9614-1)
STI: sti_from_impulse_response (indirect method: IEC 61260 octave bank,
Schroeder MTF at the 14 modulation frequencies, optional SNR/masking/
reception-threshold corrections per Tables A.2/A.3, +-15 dB clip, male
alpha/beta weighting), stipa() direct method and an Ed. 5-conformant
stipa_signal() generator using the revised A.6.1 male spectrum. Ed. 4
PDF is the primary source; Ed. 5 deltas are source-attributed in the
constants (MathWorks Ed. 5 compliance doc, zawi01/stipa - numeric
values only, no GPL code). Verified: the six A.2.2 weighting pairs
exact to 0.001, eleven m<->STI pairs, masking control points,
exponential decays vs the Schroeder closed form at four T60 values,
STIPA loop-back 0.998 and monotonic SNR degradation.
Intensity: sound_intensity() cross-spectral p-p method
(I = -Im{G12}/(2pi f rho dr)) with octave/third-octave integration,
pressure-intensity index, direction, finite-difference bias correction
validated against IEC 61043 Table 3, plus ISO 9614-1 Annex A field
indicators (F2/F3/F4) and the dynamic-capability criterion (Ld = dpI0-K,
Table 1). Verified against exact plane-wave and standing-wave physics.
415 tests, mypy strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: new guide pages, refreshed landing and README for the expanded scope
Psychoacoustics & Speech Intelligibility and Sound Intensity guide pages
(EN, docs + site with sidebar entries), the ISO 1996-2 and ECMA-74
position diagrams finally embedded in the levels guide (EN/ES), and the
outdated landing page (EN/ES), README highlights/docs table and
changelog brought up to the real scope - the hero and cards now name
the thirteen standards under conformance test instead of the original
two.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic pages, figures, diagrams and theory for psychoacoustics and intensity
Three new audited figures in four language/theme variants (specific
loudness pattern narrowband-vs-broadband, STI vs T60 with the Annex F
rating bands against the analytic Schroeder curve, and plane-vs-standing
wave intensity panels showing the pressure-intensity index), two new
setup diagrams (p-p probe with the spacer dimension, STI measurement
chain), Spanish twins of the two new guide pages, three theory sections
(Zwicker chain, MTF/STI math, intensity estimator with its bias) in
EN docs, EN site and ES site with GitHub-safe math, and API rows for
all thirteen new exports in the three reference tables.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* test: track the ISO 532-1 Annex B.4 pulse WAVs (were gitignored)
The global *.wav ignore silently excluded the four normative tone-pulse
fixtures, so CI failed with FileNotFoundError on every OS while local
runs passed against the untracked files. Force-added with an explicit
gitignore exception.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address PR 80 review round 1
- docs: use the real dynamic_capability_index signature and keep the
intensity example bands under the 12 mm spacer validity ceiling
- docs: calibration example wording (raw recording, not already-Pa)
- changelog: merge the duplicated Unreleased Added sections
- loudness: reject non-finite inputs and pathological resampling ratios
(gcd-1 rates like 44101 Hz) with clear errors, regression-tested
- tests: anchor the Aures/von Bismarck variants to the 1 acum reference
within 0.05 acum instead of a loose sanity bound
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Didactic documentation: theory everywhere, bilingual figures, setup diagrams, parameter tables (#77)
* docs: harden diagram engine per visual audit
- dim() draws real witness lines from the measured points to the offset
dimension line (the offset=0 path emitted zero-length lines); vertical
labels sit left of the line, clear of masts and figures
- env diagram: the 4 m dimension now measures the mic axis itself and
the flush-mounted label moved to the clear zone between masts
- tonality top view: the 1.00 m dimension connects face and microphone
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual diagram variants (EN/ES x light/dark)
Every setup diagram is now emitted in four variants; Spanish strings
(including decimal commas) come from a translation table applied by the
SVG engine, and layouts were adjusted where the longer Spanish labels
collided (env titles, processing-chain box width, calibration output
label, tonality dimension label side).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: bilingual figure variants for the ES site (EN/ES x light/dark)
generate_graphs.py now emits every figure in four variants: a Spanish
translation table (~75 exact strings + parametrized patterns) is applied
to the figure's Text artists at savefig time, so the generator functions
stay single-language internally. Spanish output uses UNE terminology
(ponderación temporal, líneas isofónicas, fonios, ráfaga) and a uniform
decimal comma (annotations and tick labels included); code identifiers
and normative mode names (Fast/Slow/Impulse) stay untranslated. The ES
site pages now reference the _es/_es_dark variants (56 URLs). The ES set
passed a 10-figure visual audit (10/10 approved, no blockers).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic calibration page - theory, setup diagram, stability figure, parameter table
Adds the sensitivity-factor derivation with the calibration-chain SVG,
a new autogenerated calibration_stability figure (stable vs 3% AM tone
against the IEC 60942:2017 class 1 deviation band; 4 language/theme
variants; the ES decimal-comma pass now preserves clause numbers like
5.3.3), and a full parameter table for calculate_sensitivity - EN and
ES in parity.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: SEL concept, Lden 24h profile and annotated TNR spectrum figures
Three new didactic figures for the levels guide, each in four
language/theme variants: sel_concept (pass-by event vs its Leq and the
equal-energy 1 s SEL block, dBFS mode), lden_profile (synthetic urban
24 h LAeq with colored day/evening/night bands and the +5/+10 weighted
period levels clearly separated from the composite Lden), and
tonality_spectrum (averaged Hann spectrum with the critical band, the
detected tone and the live TNR value vs its criterion, computed by the
library itself).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: didactic levels guide, theory extensions and refreshed why-phonometry
- levels guide (EN docs+site): energy-mean rationale for Leq, percentile
semantics for LN, SEL and noise-dose theory with the new figures
embedded, TNR critical-band explanation with the annotated spectrum,
Lden profile figure, and parameter tables (type/units/range/default)
for every level function including the spectrogram
- theory page: five new sections (G-weighting pole/zero derivation,
ISO 226 formulae, ECMA-418-1 TNR/PR math, event/dose metrics,
ISO 1996-1 descriptors) with cross-references to the guides
- why-phonometry: rewritten around the conformance-testing story with
the per-standard verification table and honest ecosystem positioning
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: weighting/time-weighting theory and parameter tables; fix math-block delimiters
The physiological origin of A/C (inverted 40/100-phon contours, the four
IEC corner frequencies) and the exponential-detector derivation with the
tau semantics, each with full parameter tables. Display math inserted by
the docs expansion now always uses block-style $$ delimiters on their
own lines - mid-line multi-line $$ blocks silently derailed remark
parsing and truncated every heading after them (caught because the
built pages lost their anchor ids); also replaced a raw < in a table.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: processing-chain and multirate diagrams, filter-bank math, streaming patterns
- getting-started embeds the processing-chain diagram as a guided map of
the guides
- filter-banks gains the IEC 61260-1 base-10 band math (G, fm, band
edges), a new multirate-decimation diagram (d5, four language/theme
variants) and the full octavefilter/OctaveFilterBank parameter table
- block-processing gains the canonical real-time level-meter loop
(validated against the actual API - TimeWeighting is inherently
stateful) and a stateful-constraints table
- multichannel gains the accepted-shapes table
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: Spanish parity for the didactic expansion
Every enriched page now has its Spanish twin: levels (theory, three new
figures via _es variants, six parameter tables), weighting and
time-weighting (curve-origin and exponential-detector sections),
filter-banks (fractional-band math, multirate diagram, full parameter
table - terminology unified on 'decimación'), getting-started
(processing-chain map), block-processing (real-time meter pattern and
stateful constraints), multichannel (shapes table), theory (five new
sections) and a full rewrite of why-phonometry around the conformance
story. API reference now covers all 27 public exports in EN and ES
(added ToneAssessment and CalibrationWarning rows). UNE terminology and
Spanish decimal commas throughout; site builds with all links valid.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: audited fixes - Spanish tick commas and multirate note
Final visual-audit round: the d5 diagram now shows the no-decimation
note on the 16 kHz row in both languages, and Spanish figures render
every numeric tick with a decimal comma (FixedFormatter sequences are
rewritten in place; set_xticklabels-style FuncFormatters and plain
linear ScalarFormatters are wrapped - the first naive wrapper broke
ScalarFormatter ticks entirely and was caught visually).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs(site): language selector in the mobile header, scrollable display math
Custom Header component (default markup plus a compact icon-only
LanguageSelect visible below the md breakpoint, where Starlight hides
the whole right group behind the hamburger menu) and overflow-x on
katex-display so wide formulas scroll inside their box on phones.
Verified with Playwright at 390 px in EN and ES.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: address review feedback on the didactic docs
- levels tables: spectrogram calibration_factor/dbfs marked constructor-
only, overlap range as 0 <= overlap < 1, composite hours constraints,
ln_levels shared-semantics row filled; ES translation leftovers and
the 'delante' typo fixed
- block-processing: y[..., -1] so the meter loop is multichannel-safe;
high_accuracy wording matches the real behavior (default resolves to
False, explicit True raises)
- API: CalibrationWarning row states the fs/validate preconditions (3 files)
- weighting: high_accuracy default column and oversampling claim made
precise (8x cap; silently ignored for G); ES row in parity
- filter-banks: 25 Hz relative bandwidth corrected to 0.024% of Nyquist
(EN/ES); verify_filter_class classes documented as 1/2/None
- generate_graphs: dropped the global plt.savefig monkey-patch - the
translation now runs inside themed_path(), which every generator
already calls at save time (verified output identical)
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
docs: building and structure-borne didactics, five rig diagrams and verified references (#193)
* docs: five structure-borne rig diagrams (ISO 9052-1, ISO 7626, ISO 10846, EN 15657, EN 12354-5)
Deterministic SVG builders with shared spring, accelerometer and exciter
helpers; light/dark and EN/ES variants of the dynamic-stiffness resonance
rig, the mobility beam rig, the direct/indirect transfer-stiffness stacks,
the reception plate and the EN 12354-5 installed-paths cross-section.
* docs: lab-vs-field quantities map and C/Ctr interpretation for the insulation guides
The apostrophe convention and flanking inclusion spelled out across the
trio, the extended lab/field quantities table, a didactic reading of the
spectrum adaptation terms, the measurement-prediction-check loop, and
verified References sections (Hopkins, Vigran, ISO 717-1, ISO 16283-1) in
the three copies (docs, site EN, site ES).
* docs: didactic depth for the structure-borne measurement guides
Rig diagrams embedded and prose added in all three copies: resonance-method
assumptions and preload pitfalls (EN 29052-1), how to read a mobility plot
and the ISO 7626-2 arrangement, why the blocked force and the frequency
split of the ISO 10846 methods, when the radiation-factor assumption breaks
(ISO/TS 7849), the reception-plate rationale (EN 15657) and the EN 12354-5
installation-paths context, each with a verified References section.
* docs: building-acoustics and structure-borne groups in the global bibliography
Hopkins, Vigran and Cremer/Heckl/Petersson with verified DOIs, the ISO
catalogue entries cited by the new References sections, and back-links to
the citing guides in the three bibliography copies.
* docs: legibility fixes in the mobility, transfer-stiffness and reception-plate diagrams
The driving-point caption clears the suspension spring, the Spanish
impedance-head caption clears the exciter stem, the excitation-mass boxes
fit the Spanish label, the indirect formula uses a consistent glyph style
and the Spanish source-quantities heading keeps a right margin.
* docs: precision and wording fixes in the new building and structure-borne prose
The radiation-factor caveat now qualifies accuracy rather than the bound,
Part 2 is tied explicitly to the radiation-factor problem, the survey
method keeps one Spanish term per page, the impedance-head note no longer
overstates, and Spanish register fixes (recrecido, diferencia, anclan) plus
site bibliography link texts aligned to the site page titles.
* docs: address review feedback on the building and structure-borne guides
- Field insulation guide: carry the spectrum adaptation terms on the field
descriptors (R'w + Ctr for facades, DnT,w + C between dwellings), matching
the example requirements of ISO 717-1, 5.3
- Transfer stiffness: state the ISO 10846-2 direct-method range from its
1 Hz scope bound instead of arbitrarily low frequencies, and say the
output is either rigidly blocked or loaded with a known mass
- Mechanical mobility: restrict the mobility-peak damping reading to the
isolated viscously damped resonator, present the soft free-free suspension
as the usual ISO 7626-2 arrangement rather than a requirement (clause 5),
and describe ISO 7626-5 as impact excitation with a non-attached exciter
whose spectrum is set by the impactor mass and tip stiffness
- Installed-paths diagram: render the EN 12354-5 Formula 17 path combination
as an energetic sum, 10 lg of the summed 10^(L/10) terms
- Spanish wording: parallel 'o bien ... o bien' in the transfer-stiffness
rig sentence and 'luego' in the resonance-rig diagram formula
feat: measurement uncertainty (GUM ISO/IEC Guide 98-3:2008 + Monte Carlo Supplement 1) (#102)
Adds a `phonometry.uncertainty` module implementing the two propagation methods of the GUM:
* Law of propagation of uncertainty (ISO/IEC Guide 98-3:2008, clause 5) — `combine_uncertainty` builds the combined standard uncertainty from central-difference sensitivity coefficients, with optional input correlations (validated for shape, symmetry, unit diagonal and positive-semidefiniteness), Welch-Satterthwaite effective degrees of freedom (Annex G.4) and the expanded uncertainty U = k*uc (clause 6).
* Monte Carlo method (ISO/IEC Guide 98-3-1:2008, Supplement 1, clause 7) — `monte_carlo` propagates the input PDFs and returns the estimate, its standard uncertainty and the probabilistically symmetric coverage interval (clause 7.7).
Type B quantities from a half-width: `rectangular` (a/sqrt3), `triangular` (a/sqrt6), `u_shaped` (a/sqrt2). Results expose `.expanded()` and `.plot()` (uncertainty budget).
Validated against the Guides' worked examples: additive uc=2.0 (Suppl. 1, 9.2), coverage factor k=2.92 at p=0.99/v=16 (Table G.2), Welch-Satterthwaite v_eff=40 (Annex G.4), Monte Carlo interval [-3.88, 3.88] (Suppl. 1, 9.2.3). Conformance 79/79.
Includes the budget/Monte-Carlo figure, the two-lane GUM-vs-Monte-Carlo diagram (EN/ES, light/dark), the repo doc and the EN/ES site guides under a new "Metrology & uncertainty" section.
feat: measurement uncertainty (GUM ISO/IEC Guide 98-3:2008 + Monte Carlo Supplement 1) (#102)
Adds a `phonometry.uncertainty` module implementing the two propagation methods of the GUM:
* Law of propagation of uncertainty (ISO/IEC Guide 98-3:2008, clause 5) — `combine_uncertainty` builds the combined standard uncertainty from central-difference sensitivity coefficients, with optional input correlations (validated for shape, symmetry, unit diagonal and positive-semidefiniteness), Welch-Satterthwaite effective degrees of freedom (Annex G.4) and the expanded uncertainty U = k*uc (clause 6).
* Monte Carlo method (ISO/IEC Guide 98-3-1:2008, Supplement 1, clause 7) — `monte_carlo` propagates the input PDFs and returns the estimate, its standard uncertainty and the probabilistically symmetric coverage interval (clause 7.7).
Type B quantities from a half-width: `rectangular` (a/sqrt3), `triangular` (a/sqrt6), `u_shaped` (a/sqrt2). Results expose `.expanded()` and `.plot()` (uncertainty budget).
Validated against the Guides' worked examples: additive uc=2.0 (Suppl. 1, 9.2), coverage factor k=2.92 at p=0.99/v=16 (Table G.2), Welch-Satterthwaite v_eff=40 (Annex G.4), Monte Carlo interval [-3.88, 3.88] (Suppl. 1, 9.2.3). Conformance 79/79.
Includes the budget/Monte-Carlo figure, the two-lane GUM-vs-Monte-Carlo diagram (EN/ES, light/dark), the repo doc and the EN/ES site guides under a new "Metrology & uncertainty" section.
feat: measurement uncertainty (GUM ISO/IEC Guide 98-3:2008 + Monte Carlo Supplement 1) (#102)
Adds a `phonometry.uncertainty` module implementing the two propagation methods of the GUM:
* Law of propagation of uncertainty (ISO/IEC Guide 98-3:2008, clause 5) — `combine_uncertainty` builds the combined standard uncertainty from central-difference sensitivity coefficients, with optional input correlations (validated for shape, symmetry, unit diagonal and positive-semidefiniteness), Welch-Satterthwaite effective degrees of freedom (Annex G.4) and the expanded uncertainty U = k*uc (clause 6).
* Monte Carlo method (ISO/IEC Guide 98-3-1:2008, Supplement 1, clause 7) — `monte_carlo` propagates the input PDFs and returns the estimate, its standard uncertainty and the probabilistically symmetric coverage interval (clause 7.7).
Type B quantities from a half-width: `rectangular` (a/sqrt3), `triangular` (a/sqrt6), `u_shaped` (a/sqrt2). Results expose `.expanded()` and `.plot()` (uncertainty budget).
Validated against the Guides' worked examples: additive uc=2.0 (Suppl. 1, 9.2), coverage factor k=2.92 at p=0.99/v=16 (Table G.2), Welch-Satterthwaite v_eff=40 (Annex G.4), Monte Carlo interval [-3.88, 3.88] (Suppl. 1, 9.2.3). Conformance 79/79.
Includes the budget/Monte-Carlo figure, the two-lane GUM-vs-Monte-Carlo diagram (EN/ES, light/dark), the repo doc and the EN/ES site guides under a new "Metrology & uncertainty" section.
feat: measurement uncertainty (GUM ISO/IEC Guide 98-3:2008 + Monte Carlo Supplement 1) (#102)
Adds a `phonometry.uncertainty` module implementing the two propagation methods of the GUM:
* Law of propagation of uncertainty (ISO/IEC Guide 98-3:2008, clause 5) — `combine_uncertainty` builds the combined standard uncertainty from central-difference sensitivity coefficients, with optional input correlations (validated for shape, symmetry, unit diagonal and positive-semidefiniteness), Welch-Satterthwaite effective degrees of freedom (Annex G.4) and the expanded uncertainty U = k*uc (clause 6).
* Monte Carlo method (ISO/IEC Guide 98-3-1:2008, Supplement 1, clause 7) — `monte_carlo` propagates the input PDFs and returns the estimate, its standard uncertainty and the probabilistically symmetric coverage interval (clause 7.7).
Type B quantities from a half-width: `rectangular` (a/sqrt3), `triangular` (a/sqrt6), `u_shaped` (a/sqrt2). Results expose `.expanded()` and `.plot()` (uncertainty budget).
Validated against the Guides' worked examples: additive uc=2.0 (Suppl. 1, 9.2), coverage factor k=2.92 at p=0.99/v=16 (Table G.2), Welch-Satterthwaite v_eff=40 (Annex G.4), Monte Carlo interval [-3.88, 3.88] (Suppl. 1, 9.2.3). Conformance 79/79.
Includes the budget/Monte-Carlo figure, the two-lane GUM-vs-Monte-Carlo diagram (EN/ES, light/dark), the repo doc and the EN/ES site guides under a new "Metrology & uncertainty" section.
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
docs: outdoor and environmental didactics, measurement-geometry diagrams and verified references (#199)
* docs: IEC 61400-11 measurement-geometry and ground-reflection setup diagrams
Two new deterministic SVG diagrams (4 variants each, EN/ES x light/dark):
- diagram_wind_turbine_iec61400: side view of the turbine with the downwind
ground-board microphone at R0 = H + D/2, the slant distance R1 to the
rotor centre, the met mast, the board inclination angle and the Figure 3
plan-view position pattern (reference position downwind, optional
positions at +/-60 degrees and upwind).
- diagram_ground_reflection: source and receiver over a reflecting plane
with the direct ray, the specular reflection unfolded through the image
source, the path difference delta = r2 - r1 and the interference phase.
* docs: outdoor-propagation didactics: image source, favourable conditions, barrier pitfalls, CNOSSOS-EU
Expand the outdoor-propagation guide in the three trees (docs EN, site EN,
site ES):
- New subsection on the image source behind the ground effect, with the
ground-reflection diagram: path difference, interference phase, the hard
-3 dB result and the porous-ground notch that Table 3 parameterizes.
- New closing section on scope and pitfalls: what the favourable propagation
conditions of Clause 5 mean and why the method predicts the audible case;
barrier fine print (the 20/25 dB caps, the Kmet erosion over distance, the
modest double-diffraction bonus, the Abar = Dz - Agr fold-in and the
Clause 7.4 qualification rules); and an ISO 9613-2 vs CNOSSOS-EU
comparison covering scope, methodology and why the two frameworks disagree
on the same geometry.
- References section with verified entries: Salomons, Attenborough & Van
Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report and the ISO 9613-1/-2
catalogue pages.
* docs: impulse-prominence context: category adjustments, ISO/PAS 1996-3 and logging caveats
Add a short standards-context section to the impulse-prominence guide in the
three trees: the fixed ISO 1996-1:2016 Table A.1 category adjustments (5 dB
regular, 12 dB highly impulsive) that the measured prominence replaces with
a graduated KI, the ISO/PAS 1996-3:2022 successor built on the same
onset-rate prominence, and two practical caveats (time-weighting-F smoothing
of very short impulses and prominence-not-energy). References section with
the Nordtest method page and the ISO 1996-1 / ISO/PAS 1996-3 catalogue
pages, all verified.
* docs: wind-turbine-noise didactics: measurement geometry, apparent power and wind-speed binning
Expand the wind-turbine-noise guide in the three trees:
- Embed the IEC 61400-11 measurement-geometry diagram (ground-board
microphone at R0 = H + D/2, slant distance R1, met mast, plan-view
position pattern).
- New subsection on why the apparent sound power is not a true LW: an
equivalent point source at the rotor centre matched to one downwind
position, with directivity folded in, comparable across turbines because
the geometry scales with the machine.
- New subsection on wind-speed bins and standardized conditions: 0.5 m/s
bins centred on integer and half-integer hub-height speeds, wind speed
derived from electric power through the power curve, the 0.8 to 1.3 times
85 %-power range, background-margin rules, and the Formula (29) conversion
to 10 m height over the 0.05 m reference roughness length.
- References section: IEC 61400-11:2012+AMD1:2018 CSV, IEC TS 61400-14:2005
and ISO 1996-2:2017, all verified.
* docs: outdoor and environmental sound group in the global bibliography
Add the Outdoor and environmental sound section to the bibliography in the
three trees, with back-links to the citing guides: Salomons, Attenborough &
Van Renterghem, Maekawa 1968, the CNOSSOS-EU JRC report, ISO 9613-1/-2,
ISO 1996-1/-2, NT ACOU 112, ISO/PAS 1996-3 and IEC 61400-11/-14. The
ISO 1996-2 entry also back-fills the tone-audibility citation that was
missing from the global list.
* docs: review fixes for the outdoor and environmental wave
- Bind the tonal-audibility criterion IEC 61400-11 reuses to the Annex C of
the 2007 edition of ISO 1996-2 (the 2017 edition carries the tonal methods
in Annexes J and K), in the wind-turbine References and the bibliography.
- ISO 3744 samples the pressure field over the enveloping surface; intensity
integration is ISO 9614 territory.
- IEC 61400-11 background rule: a margin of 3 dB or less voids the bin (the
boundary case included).
- Ground-reflection diagram: parenthesise the reflection-coefficient note so
SVG whitespace collapsing cannot glue it to the formula; move the
wind-turbine ground-board label clear of the R1 ray.
- Spanish polish: unify onset rate as tasa de crecimiento, replace the
recomprar calque with compensar.
* docs: review refinements in the outdoor and environmental guides
---------
Co-authored-by: José M. Requena Plens <jmrplens@icloud.com>
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Audit pass 11a: seven new documentation diagrams (#121)
* Audit pass 11a: seven new documentation diagrams
Add SVG flow diagrams for the seven topics the audit flagged as having no
schematic: the exponential-detector chain of the time weightings
(IEC 61672-1), stateful vs reset block processing, the multichannel
array-shape flow, the open-plan spatial-decay line (ISO 3382-3), the
ISO 12999-1 uncertainty pipeline, the ISO 11654 absorption-rating flow and
the Zwicker loudness-model chain (ISO 532-1).
Each is generated deterministically by generate_diagrams.py in the four
EN/ES x light/dark variants, with every Spanish label added to the _ES
table (decimals localised to commas), and embedded in the repo docs and
both site trees beside the existing worked-example plots.
* Fix ISO 532-1 table citations in the Zwicker diagram
Review of the diagram against loudness_zwicker.py found two mislabelled
tables: the equal-loudness correction and lower-critical-band grouping is
Table A.3 (not A.4), and the threshold in quiet LTQ is Table A.6 (not A.3).
Reassign the a0/DDF/LTQ corrections to the core-loudness step (Tables
A.4-A.7) where they belong, update the Spanish labels, and align the ES
psychoacoustics alt text with the guide's own term "sonos" (was "sonios").
Use a real polar response for the ISO 17497-2 diffusion oracle (#344)
* Use a real polar response for the ISO 17497-2 diffusion oracle
Replace the hand-made four-level diffusion anchor with a real free-field
polar response: a boundary-element (COMSOL) prediction of an N = 7
quadratic-residue diffuser and its flat reference panel at 1000 Hz, normal
incidence, reduced to the standard 37-receiver single-plane semicircle
(5 deg spacing, -90 to +90 deg) in the plane of maximum diffusion. The 37
arc points are coplanar to 3.4e-3 of unit radius, so the equal-area
Formula (5) applies exactly; levels are L_i = 20 lg |p_i|.
- reference_data: commit the 37 QRD and flat-reference arc levels and the
directional diffusion coefficients d_theta = 0.7572 (QRD) and 0.1391
(flat) and the normalised d_theta,n = 0.7180 (Formula (7)), with full
provenance. For context the full dense hemisphere gives 0.5007/0.1487/
0.4135 (energy) and reproduces the source's own value under the amplitude
convention.
- conformance: three real-data rows (Formula (5) twice, Formula (7)),
reproduced to 1e-6; regenerate docs/CONFORMANCE.md (412/412 pass).
- tests: clean-room checks that re-derive Formula (5) from the levels
independently of the library kernel.
- Surface Scattering guide (English and Spanish, plus the GitHub mirror)
and the theory anchor now use the cited real QRD example; regenerate the
polar figure (d = 0.76) and llms-full.txt.
* Regenerate conformance and references after rebase
* Correct the diffusion oracle provenance to an in-house COMSOL FEM simulation
The single-plane QRD field is the maintainer's own COMSOL finite-element
free-field simulation cross-validated against an independent MATLAB
implementation of ISO 17497-2 Formula (5), not a boundary-element method and
not a third-party published measurement; drop the unverifiable thesis
citation and the mislabelled method across the guide, its mirror and the
oracle provenance.
* Make the diffusion-oracle provenance consistent in the test module
Match the reference-data provenance: in-house COMSOL finite-element simulation
cross-validated against an independent MATLAB implementation, not a
boundary-element 2018 thesis and not a measurement; rename the tests to
_matches_simulation_oracle.
Use a real polar response for the ISO 17497-2 diffusion oracle (#344)
* Use a real polar response for the ISO 17497-2 diffusion oracle
Replace the hand-made four-level diffusion anchor with a real free-field
polar response: a boundary-element (COMSOL) prediction of an N = 7
quadratic-residue diffuser and its flat reference panel at 1000 Hz, normal
incidence, reduced to the standard 37-receiver single-plane semicircle
(5 deg spacing, -90 to +90 deg) in the plane of maximum diffusion. The 37
arc points are coplanar to 3.4e-3 of unit radius, so the equal-area
Formula (5) applies exactly; levels are L_i = 20 lg |p_i|.
- reference_data: commit the 37 QRD and flat-reference arc levels and the
directional diffusion coefficients d_theta = 0.7572 (QRD) and 0.1391
(flat) and the normalised d_theta,n = 0.7180 (Formula (7)), with full
provenance. For context the full dense hemisphere gives 0.5007/0.1487/
0.4135 (energy) and reproduces the source's own value under the amplitude
convention.
- conformance: three real-data rows (Formula (5) twice, Formula (7)),
reproduced to 1e-6; regenerate docs/CONFORMANCE.md (412/412 pass).
- tests: clean-room checks that re-derive Formula (5) from the levels
independently of the library kernel.
- Surface Scattering guide (English and Spanish, plus the GitHub mirror)
and the theory anchor now use the cited real QRD example; regenerate the
polar figure (d = 0.76) and llms-full.txt.
* Regenerate conformance and references after rebase
* Correct the diffusion oracle provenance to an in-house COMSOL FEM simulation
The single-plane QRD field is the maintainer's own COMSOL finite-element
free-field simulation cross-validated against an independent MATLAB
implementation of ISO 17497-2 Formula (5), not a boundary-element method and
not a third-party published measurement; drop the unverifiable thesis
citation and the mislabelled method across the guide, its mirror and the
oracle provenance.
* Make the diffusion-oracle provenance consistent in the test module
Match the reference-data provenance: in-house COMSOL finite-element simulation
cross-validated against an independent MATLAB implementation, not a
boundary-element 2018 thesis and not a measurement; rename the tests to
_matches_simulation_oracle.
Use a real polar response for the ISO 17497-2 diffusion oracle (#344)
* Use a real polar response for the ISO 17497-2 diffusion oracle
Replace the hand-made four-level diffusion anchor with a real free-field
polar response: a boundary-element (COMSOL) prediction of an N = 7
quadratic-residue diffuser and its flat reference panel at 1000 Hz, normal
incidence, reduced to the standard 37-receiver single-plane semicircle
(5 deg spacing, -90 to +90 deg) in the plane of maximum diffusion. The 37
arc points are coplanar to 3.4e-3 of unit radius, so the equal-area
Formula (5) applies exactly; levels are L_i = 20 lg |p_i|.
- reference_data: commit the 37 QRD and flat-reference arc levels and the
directional diffusion coefficients d_theta = 0.7572 (QRD) and 0.1391
(flat) and the normalised d_theta,n = 0.7180 (Formula (7)), with full
provenance. For context the full dense hemisphere gives 0.5007/0.1487/
0.4135 (energy) and reproduces the source's own value under the amplitude
convention.
- conformance: three real-data rows (Formula (5) twice, Formula (7)),
reproduced to 1e-6; regenerate docs/CONFORMANCE.md (412/412 pass).
- tests: clean-room checks that re-derive Formula (5) from the levels
independently of the library kernel.
- Surface Scattering guide (English and Spanish, plus the GitHub mirror)
and the theory anchor now use the cited real QRD example; regenerate the
polar figure (d = 0.76) and llms-full.txt.
* Regenerate conformance and references after rebase
* Correct the diffusion oracle provenance to an in-house COMSOL FEM simulation
The single-plane QRD field is the maintainer's own COMSOL finite-element
free-field simulation cross-validated against an independent MATLAB
implementation of ISO 17497-2 Formula (5), not a boundary-element method and
not a third-party published measurement; drop the unverifiable thesis
citation and the mislabelled method across the guide, its mirror and the
oracle provenance.
* Make the diffusion-oracle provenance consistent in the test module
Match the reference-data provenance: in-house COMSOL finite-element simulation
cross-validated against an independent MATLAB implementation, not a
boundary-element 2018 thesis and not a measurement; rename the tests to
_matches_simulation_oracle.
Use a real polar response for the ISO 17497-2 diffusion oracle (#344)
* Use a real polar response for the ISO 17497-2 diffusion oracle
Replace the hand-made four-level diffusion anchor with a real free-field
polar response: a boundary-element (COMSOL) prediction of an N = 7
quadratic-residue diffuser and its flat reference panel at 1000 Hz, normal
incidence, reduced to the standard 37-receiver single-plane semicircle
(5 deg spacing, -90 to +90 deg) in the plane of maximum diffusion. The 37
arc points are coplanar to 3.4e-3 of unit radius, so the equal-area
Formula (5) applies exactly; levels are L_i = 20 lg |p_i|.
- reference_data: commit the 37 QRD and flat-reference arc levels and the
directional diffusion coefficients d_theta = 0.7572 (QRD) and 0.1391
(flat) and the normalised d_theta,n = 0.7180 (Formula (7)), with full
provenance. For context the full dense hemisphere gives 0.5007/0.1487/
0.4135 (energy) and reproduces the source's own value under the amplitude
convention.
- conformance: three real-data rows (Formula (5) twice, Formula (7)),
reproduced to 1e-6; regenerate docs/CONFORMANCE.md (412/412 pass).
- tests: clean-room checks that re-derive Formula (5) from the levels
independently of the library kernel.
- Surface Scattering guide (English and Spanish, plus the GitHub mirror)
and the theory anchor now use the cited real QRD example; regenerate the
polar figure (d = 0.76) and llms-full.txt.
* Regenerate conformance and references after rebase
* Correct the diffusion oracle provenance to an in-house COMSOL FEM simulation
The single-plane QRD field is the maintainer's own COMSOL finite-element
free-field simulation cross-validated against an independent MATLAB
implementation of ISO 17497-2 Formula (5), not a boundary-element method and
not a third-party published measurement; drop the unverifiable thesis
citation and the mislabelled method across the guide, its mirror and the
oracle provenance.
* Make the diffusion-oracle provenance consistent in the test module
Match the reference-data provenance: in-house COMSOL finite-element simulation
cross-validated against an independent MATLAB implementation, not a
boundary-element 2018 thesis and not a measurement; rename the tests to
_matches_simulation_oracle.
Multiple and partial coherence for MISO systems (Bendat & Piersol) (#295)
* Multiple and partial coherence for MISO systems (Bendat & Piersol)
Add miso_coherence for the multiple-input/single-output coherence
functions of Bendat & Piersol, Random Data 4e, Chapter 7. From the Welch
cross-spectral matrix of two or three partially correlated inputs and one
output it reports:
- the ordinary coherence of each input with the output (Eq. 7.109);
- the multiple coherence explained by all inputs jointly (Eq. 7.35), equal
to SNR/(1+SNR) for additive output noise of known level;
- the partial coherences (Eq. 7.87, 4th-edition total-output denominator)
obtained by the Gaussian-elimination conditioning of Section 7.3
(Eq. 7.94), so a source that only correlates with the true cause is no
longer credited for it;
- the partial coherent output spectra that decompose the output power
source by source (Eq. 7.86, with the shares plus the residual noise
reconstructing the output exactly), and a dominant_input() helper for the
strongest source per band.
The frozen MISOCoherenceResult also carries the Section 9.3 random errors
(the i-th ordered input keeps nd-(i-1) effective averages) and an EN/ES
.plot(). The estimators reuse the Welch core of spectra.py, so a MISO
coherence and a power_spectral_density taken with the same segment length
are consistent bin by bin.
The conditioning is pinned to the exact rational values of Problem 7.2
(G22.1 = 4/3, G2y.1 = 4/3, Gyy.1 = 13/3, partial coherence 2/15, multiple
coherence 0.7), and the identities are checked against the SNR relation and
the uncorrelated-input case where the partial coherences reduce to the
ordinary ones and their sum is the multiple coherence. Five conformance
rows, a test suite, an EN/ES guide with a worked figure, and the API
reference, bibliography and taxonomy entries accompany the module.
* Address MISO coherence review findings
- Give the coherent-output fills a fixed dB baseline derived once from the
finite dynamic range of the panel (new _finite_db_floor), clip the plotted
levels to it and set the y-limits explicitly, so a coherent output that
dips to zero no longer drags the axis through get_ylim() inside the loop.
- Share one pivot-safety mask between the coherent-output accumulation and
the Schur update (new _pivot_safe): a near-singular conditioned pivot is
now gated identically in both places, so the power decomposition
(sum of contributions + residual = Gyy) closes bin by bin. Add a singular
(perfectly collinear) and a near-collinear test covering the invariant.
- Reword the conformance description that contained literal pipe characters
("abs(G2y.1)^2/G22.1") so the generated CONFORMANCE.md table is not
corrupted; regenerate the report.
Multiple and partial coherence for MISO systems (Bendat & Piersol) (#295)
* Multiple and partial coherence for MISO systems (Bendat & Piersol)
Add miso_coherence for the multiple-input/single-output coherence
functions of Bendat & Piersol, Random Data 4e, Chapter 7. From the Welch
cross-spectral matrix of two or three partially correlated inputs and one
output it reports:
- the ordinary coherence of each input with the output (Eq. 7.109);
- the multiple coherence explained by all inputs jointly (Eq. 7.35), equal
to SNR/(1+SNR) for additive output noise of known level;
- the partial coherences (Eq. 7.87, 4th-edition total-output denominator)
obtained by the Gaussian-elimination conditioning of Section 7.3
(Eq. 7.94), so a source that only correlates with the true cause is no
longer credited for it;
- the partial coherent output spectra that decompose the output power
source by source (Eq. 7.86, with the shares plus the residual noise
reconstructing the output exactly), and a dominant_input() helper for the
strongest source per band.
The frozen MISOCoherenceResult also carries the Section 9.3 random errors
(the i-th ordered input keeps nd-(i-1) effective averages) and an EN/ES
.plot(). The estimators reuse the Welch core of spectra.py, so a MISO
coherence and a power_spectral_density taken with the same segment length
are consistent bin by bin.
The conditioning is pinned to the exact rational values of Problem 7.2
(G22.1 = 4/3, G2y.1 = 4/3, Gyy.1 = 13/3, partial coherence 2/15, multiple
coherence 0.7), and the identities are checked against the SNR relation and
the uncorrelated-input case where the partial coherences reduce to the
ordinary ones and their sum is the multiple coherence. Five conformance
rows, a test suite, an EN/ES guide with a worked figure, and the API
reference, bibliography and taxonomy entries accompany the module.
* Address MISO coherence review findings
- Give the coherent-output fills a fixed dB baseline derived once from the
finite dynamic range of the panel (new _finite_db_floor), clip the plotted
levels to it and set the y-limits explicitly, so a coherent output that
dips to zero no longer drags the axis through get_ylim() inside the loop.
- Share one pivot-safety mask between the coherent-output accumulation and
the Schur update (new _pivot_safe): a near-singular conditioned pivot is
now gated identically in both places, so the power decomposition
(sum of contributions + residual = Gyy) closes bin by bin. Add a singular
(perfectly collinear) and a near-collinear test covering the invariant.
- Reword the conformance description that contained literal pipe characters
("abs(G2y.1)^2/G22.1") so the generated CONFORMANCE.md table is not
corrupted; regenerate the report.
Multiple and partial coherence for MISO systems (Bendat & Piersol) (#295)
* Multiple and partial coherence for MISO systems (Bendat & Piersol)
Add miso_coherence for the multiple-input/single-output coherence
functions of Bendat & Piersol, Random Data 4e, Chapter 7. From the Welch
cross-spectral matrix of two or three partially correlated inputs and one
output it reports:
- the ordinary coherence of each input with the output (Eq. 7.109);
- the multiple coherence explained by all inputs jointly (Eq. 7.35), equal
to SNR/(1+SNR) for additive output noise of known level;
- the partial coherences (Eq. 7.87, 4th-edition total-output denominator)
obtained by the Gaussian-elimination conditioning of Section 7.3
(Eq. 7.94), so a source that only correlates with the true cause is no
longer credited for it;
- the partial coherent output spectra that decompose the output power
source by source (Eq. 7.86, with the shares plus the residual noise
reconstructing the output exactly), and a dominant_input() helper for the
strongest source per band.
The frozen MISOCoherenceResult also carries the Section 9.3 random errors
(the i-th ordered input keeps nd-(i-1) effective averages) and an EN/ES
.plot(). The estimators reuse the Welch core of spectra.py, so a MISO
coherence and a power_spectral_density taken with the same segment length
are consistent bin by bin.
The conditioning is pinned to the exact rational values of Problem 7.2
(G22.1 = 4/3, G2y.1 = 4/3, Gyy.1 = 13/3, partial coherence 2/15, multiple
coherence 0.7), and the identities are checked against the SNR relation and
the uncorrelated-input case where the partial coherences reduce to the
ordinary ones and their sum is the multiple coherence. Five conformance
rows, a test suite, an EN/ES guide with a worked figure, and the API
reference, bibliography and taxonomy entries accompany the module.
* Address MISO coherence review findings
- Give the coherent-output fills a fixed dB baseline derived once from the
finite dynamic range of the panel (new _finite_db_floor), clip the plotted
levels to it and set the y-limits explicitly, so a coherent output that
dips to zero no longer drags the axis through get_ylim() inside the loop.
- Share one pivot-safety mask between the coherent-output accumulation and
the Schur update (new _pivot_safe): a near-singular conditioned pivot is
now gated identically in both places, so the power decomposition
(sum of contributions + residual = Gyy) closes bin by bin. Add a singular
(perfectly collinear) and a near-collinear test covering the invariant.
- Reword the conformance description that contained literal pipe characters
("abs(G2y.1)^2/G22.1") so the generated CONFORMANCE.md table is not
corrupted; regenerate the report.
Multiple and partial coherence for MISO systems (Bendat & Piersol) (#295)
* Multiple and partial coherence for MISO systems (Bendat & Piersol)
Add miso_coherence for the multiple-input/single-output coherence
functions of Bendat & Piersol, Random Data 4e, Chapter 7. From the Welch
cross-spectral matrix of two or three partially correlated inputs and one
output it reports:
- the ordinary coherence of each input with the output (Eq. 7.109);
- the multiple coherence explained by all inputs jointly (Eq. 7.35), equal
to SNR/(1+SNR) for additive output noise of known level;
- the partial coherences (Eq. 7.87, 4th-edition total-output denominator)
obtained by the Gaussian-elimination conditioning of Section 7.3
(Eq. 7.94), so a source that only correlates with the true cause is no
longer credited for it;
- the partial coherent output spectra that decompose the output power
source by source (Eq. 7.86, with the shares plus the residual noise
reconstructing the output exactly), and a dominant_input() helper for the
strongest source per band.
The frozen MISOCoherenceResult also carries the Section 9.3 random errors
(the i-th ordered input keeps nd-(i-1) effective averages) and an EN/ES
.plot(). The estimators reuse the Welch core of spectra.py, so a MISO
coherence and a power_spectral_density taken with the same segment length
are consistent bin by bin.
The conditioning is pinned to the exact rational values of Problem 7.2
(G22.1 = 4/3, G2y.1 = 4/3, Gyy.1 = 13/3, partial coherence 2/15, multiple
coherence 0.7), and the identities are checked against the SNR relation and
the uncorrelated-input case where the partial coherences reduce to the
ordinary ones and their sum is the multiple coherence. Five conformance
rows, a test suite, an EN/ES guide with a worked figure, and the API
reference, bibliography and taxonomy entries accompany the module.
* Address MISO coherence review findings
- Give the coherent-output fills a fixed dB baseline derived once from the
finite dynamic range of the panel (new _finite_db_floor), clip the plotted
levels to it and set the y-limits explicitly, so a coherent output that
dips to zero no longer drags the axis through get_ylim() inside the loop.
- Share one pivot-safety mask between the coherent-output accumulation and
the Schur update (new _pivot_safe): a near-singular conditioned pivot is
now gated identically in both places, so the power decomposition
(sum of contributions + residual = Gyy) closes bin by bin. Add a singular
(perfectly collinear) and a near-collinear test covering the invariant.
- Reword the conformance description that contained literal pipe characters
("abs(G2y.1)^2/G22.1") so the generated CONFORMANCE.md table is not
corrupted; regenerate the report.
Add slow-sound slit and Helmholtz-resonator perfect absorbers (#346)
* Add slow-sound slit and Helmholtz-resonator perfect absorbers
Introduce materials.slow_sound_absorber, a transfer-matrix model of a
rigid panel of thin closed slits loaded by an array of Helmholtz
resonators. The resonators slow the sound inside the slit and pull its
resonance into the deep-subwavelength regime, and the visco-thermal
losses of the sub-millimetre slit and of the square resonator necks and
cavities make perfect absorption possible.
slit_helmholtz_absorber predicts the oblique-incidence absorption of the
panel, returning a SlitResonatorAbsorberResult with the surface
impedance, reflection factor, absorption, retrieved effective parameters
and the full chain matrix, plus a .plot() of alpha(f) with |R| overlaid.
critical_coupling_design solves the inverse problem: it tunes the cavity
length and the slit height so the reflection zero sits on the real
frequency axis, giving perfect absorption at a chosen frequency and
angle. The building blocks slit_effective_properties,
rectangular_duct_properties and helmholtz_resonator_impedance and the
HelmholtzResonator geometry are exported alongside.
The model is pinned to its exact analytic anchors: perfect absorption at
the design frequency, the Poiseuille resistivity limits 12 eta / h^2
(slit) and 28.454 eta / w^2 (square duct), and the loss-free
effective-parameter limits (rho -> rho0, kappa -> kappa0). Adds a
conformance section, an example figure, tests, an API-reference row set,
and EN/ES guide sections.
* Keep the Sonar gate clean for the slow-sound absorber
Exempt materials.slow_sound_absorber from S107 the same way the other
scientific APIs are: its functions carry the slit and resonator geometry
alongside the shared keyword-only air state, matching the porous-absorber
and JCA signatures, so the parameter count reflects the physics rather
than incidental complexity.
Extract a shared alpha(f) + |R| overlay renderer for the layered-absorber
and slit-resonator plots so the two oblique-incidence absorber renderers
no longer duplicate their body. Output is byte-identical.
* Make the slow-sound absorber files Ruff 0.16 clean
Use dict literals for the shared air-state mappings and drop the
redundant quoted type annotations (the module already imports
annotations from __future__). Keeps the new feature files clean under
the widened Ruff 0.16 default rule set without touching unrelated files.
* Modernize the slow-sound absorber additions for ruff 0.16 and regenerate references
* Silence the unused figure handle in the slow-sound graph helper
* Clarify slow-sound docstrings and cover the optional-correction branches
Fix the trailing space in a docstring code span, state the design warning is
emitted rather than raised, correct the deep-subwavelength depth ratio in the
figure docstring, and add a test exercising the end_correction and
slit_radiation False branches.
* Regenerate API reference and llms for the slow-sound docstring fixes
* Regenerate conformance and references after rebase
* Translate the slow-sound figure strings and require convergence in the check
Add the Spanish figure-string translations for the slow-sound absorber plot
(legend, design annotation, title and the panel-depth pattern) so the ES
variant is not left in English, and make the critical-coupling conformance
check fail unless the design solver converged.
* Regenerate conformance and references after rebase
Add slow-sound slit and Helmholtz-resonator perfect absorbers (#346)
* Add slow-sound slit and Helmholtz-resonator perfect absorbers
Introduce materials.slow_sound_absorber, a transfer-matrix model of a
rigid panel of thin closed slits loaded by an array of Helmholtz
resonators. The resonators slow the sound inside the slit and pull its
resonance into the deep-subwavelength regime, and the visco-thermal
losses of the sub-millimetre slit and of the square resonator necks and
cavities make perfect absorption possible.
slit_helmholtz_absorber predicts the oblique-incidence absorption of the
panel, returning a SlitResonatorAbsorberResult with the surface
impedance, reflection factor, absorption, retrieved effective parameters
and the full chain matrix, plus a .plot() of alpha(f) with |R| overlaid.
critical_coupling_design solves the inverse problem: it tunes the cavity
length and the slit height so the reflection zero sits on the real
frequency axis, giving perfect absorption at a chosen frequency and
angle. The building blocks slit_effective_properties,
rectangular_duct_properties and helmholtz_resonator_impedance and the
HelmholtzResonator geometry are exported alongside.
The model is pinned to its exact analytic anchors: perfect absorption at
the design frequency, the Poiseuille resistivity limits 12 eta / h^2
(slit) and 28.454 eta / w^2 (square duct), and the loss-free
effective-parameter limits (rho -> rho0, kappa -> kappa0). Adds a
conformance section, an example figure, tests, an API-reference row set,
and EN/ES guide sections.
* Keep the Sonar gate clean for the slow-sound absorber
Exempt materials.slow_sound_absorber from S107 the same way the other
scientific APIs are: its functions carry the slit and resonator geometry
alongside the shared keyword-only air state, matching the porous-absorber
and JCA signatures, so the parameter count reflects the physics rather
than incidental complexity.
Extract a shared alpha(f) + |R| overlay renderer for the layered-absorber
and slit-resonator plots so the two oblique-incidence absorber renderers
no longer duplicate their body. Output is byte-identical.
* Make the slow-sound absorber files Ruff 0.16 clean
Use dict literals for the shared air-state mappings and drop the
redundant quoted type annotations (the module already imports
annotations from __future__). Keeps the new feature files clean under
the widened Ruff 0.16 default rule set without touching unrelated files.
* Modernize the slow-sound absorber additions for ruff 0.16 and regenerate references
* Silence the unused figure handle in the slow-sound graph helper
* Clarify slow-sound docstrings and cover the optional-correction branches
Fix the trailing space in a docstring code span, state the design warning is
emitted rather than raised, correct the deep-subwavelength depth ratio in the
figure docstring, and add a test exercising the end_correction and
slit_radiation False branches.
* Regenerate API reference and llms for the slow-sound docstring fixes
* Regenerate conformance and references after rebase
* Translate the slow-sound figure strings and require convergence in the check
Add the Spanish figure-string translations for the slow-sound absorber plot
(legend, design annotation, title and the panel-depth pattern) so the ES
variant is not left in English, and make the critical-coupling conformance
check fail unless the design solver converged.
* Regenerate conformance and references after rebase
Add slow-sound slit and Helmholtz-resonator perfect absorbers (#346)
* Add slow-sound slit and Helmholtz-resonator perfect absorbers
Introduce materials.slow_sound_absorber, a transfer-matrix model of a
rigid panel of thin closed slits loaded by an array of Helmholtz
resonators. The resonators slow the sound inside the slit and pull its
resonance into the deep-subwavelength regime, and the visco-thermal
losses of the sub-millimetre slit and of the square resonator necks and
cavities make perfect absorption possible.
slit_helmholtz_absorber predicts the oblique-incidence absorption of the
panel, returning a SlitResonatorAbsorberResult with the surface
impedance, reflection factor, absorption, retrieved effective parameters
and the full chain matrix, plus a .plot() of alpha(f) with |R| overlaid.
critical_coupling_design solves the inverse problem: it tunes the cavity
length and the slit height so the reflection zero sits on the real
frequency axis, giving perfect absorption at a chosen frequency and
angle. The building blocks slit_effective_properties,
rectangular_duct_properties and helmholtz_resonator_impedance and the
HelmholtzResonator geometry are exported alongside.
The model is pinned to its exact analytic anchors: perfect absorption at
the design frequency, the Poiseuille resistivity limits 12 eta / h^2
(slit) and 28.454 eta / w^2 (square duct), and the loss-free
effective-parameter limits (rho -> rho0, kappa -> kappa0). Adds a
conformance section, an example figure, tests, an API-reference row set,
and EN/ES guide sections.
* Keep the Sonar gate clean for the slow-sound absorber
Exempt materials.slow_sound_absorber from S107 the same way the other
scientific APIs are: its functions carry the slit and resonator geometry
alongside the shared keyword-only air state, matching the porous-absorber
and JCA signatures, so the parameter count reflects the physics rather
than incidental complexity.
Extract a shared alpha(f) + |R| overlay renderer for the layered-absorber
and slit-resonator plots so the two oblique-incidence absorber renderers
no longer duplicate their body. Output is byte-identical.
* Make the slow-sound absorber files Ruff 0.16 clean
Use dict literals for the shared air-state mappings and drop the
redundant quoted type annotations (the module already imports
annotations from __future__). Keeps the new feature files clean under
the widened Ruff 0.16 default rule set without touching unrelated files.
* Modernize the slow-sound absorber additions for ruff 0.16 and regenerate references
* Silence the unused figure handle in the slow-sound graph helper
* Clarify slow-sound docstrings and cover the optional-correction branches
Fix the trailing space in a docstring code span, state the design warning is
emitted rather than raised, correct the deep-subwavelength depth ratio in the
figure docstring, and add a test exercising the end_correction and
slit_radiation False branches.
* Regenerate API reference and llms for the slow-sound docstring fixes
* Regenerate conformance and references after rebase
* Translate the slow-sound figure strings and require convergence in the check
Add the Spanish figure-string translations for the slow-sound absorber plot
(legend, design annotation, title and the panel-depth pattern) so the ES
variant is not left in English, and make the critical-coupling conformance
check fail unless the design solver converged.
* Regenerate conformance and references after rebase
Add slow-sound slit and Helmholtz-resonator perfect absorbers (#346)
* Add slow-sound slit and Helmholtz-resonator perfect absorbers
Introduce materials.slow_sound_absorber, a transfer-matrix model of a
rigid panel of thin closed slits loaded by an array of Helmholtz
resonators. The resonators slow the sound inside the slit and pull its
resonance into the deep-subwavelength regime, and the visco-thermal
losses of the sub-millimetre slit and of the square resonator necks and
cavities make perfect absorption possible.
slit_helmholtz_absorber predicts the oblique-incidence absorption of the
panel, returning a SlitResonatorAbsorberResult with the surface
impedance, reflection factor, absorption, retrieved effective parameters
and the full chain matrix, plus a .plot() of alpha(f) with |R| overlaid.
critical_coupling_design solves the inverse problem: it tunes the cavity
length and the slit height so the reflection zero sits on the real
frequency axis, giving perfect absorption at a chosen frequency and
angle. The building blocks slit_effective_properties,
rectangular_duct_properties and helmholtz_resonator_impedance and the
HelmholtzResonator geometry are exported alongside.
The model is pinned to its exact analytic anchors: perfect absorption at
the design frequency, the Poiseuille resistivity limits 12 eta / h^2
(slit) and 28.454 eta / w^2 (square duct), and the loss-free
effective-parameter limits (rho -> rho0, kappa -> kappa0). Adds a
conformance section, an example figure, tests, an API-reference row set,
and EN/ES guide sections.
* Keep the Sonar gate clean for the slow-sound absorber
Exempt materials.slow_sound_absorber from S107 the same way the other
scientific APIs are: its functions carry the slit and resonator geometry
alongside the shared keyword-only air state, matching the porous-absorber
and JCA signatures, so the parameter count reflects the physics rather
than incidental complexity.
Extract a shared alpha(f) + |R| overlay renderer for the layered-absorber
and slit-resonator plots so the two oblique-incidence absorber renderers
no longer duplicate their body. Output is byte-identical.
* Make the slow-sound absorber files Ruff 0.16 clean
Use dict literals for the shared air-state mappings and drop the
redundant quoted type annotations (the module already imports
annotations from __future__). Keeps the new feature files clean under
the widened Ruff 0.16 default rule set without touching unrelated files.
* Modernize the slow-sound absorber additions for ruff 0.16 and regenerate references
* Silence the unused figure handle in the slow-sound graph helper
* Clarify slow-sound docstrings and cover the optional-correction branches
Fix the trailing space in a docstring code span, state the design warning is
emitted rather than raised, correct the deep-subwavelength depth ratio in the
figure docstring, and add a test exercising the end_correction and
slit_radiation False branches.
* Regenerate API reference and llms for the slow-sound docstring fixes
* Regenerate conformance and references after rebase
* Translate the slow-sound figure strings and require convergence in the check
Add the Spanish figure-string translations for the slow-sound absorber plot
(legend, design annotation, title and the panel-depth pattern) so the ES
variant is not left in English, and make the critical-coupling conformance
check fail unless the design solver converged.
* Regenerate conformance and references after rebase
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Sound power determination and building acoustics II: ISO 3744/3746, ISO 3741, ISO 9614-2, ISO 16283-2 + ISO 717-2, ISO 354 (#84)
* feat: ISO 3744/3746 sound power from pressure measurements
Add sound_power.py: sound power level of a noise source from sound
pressure levels over an enveloping measurement surface, ISO 3744:2010
(engineering, grade 2) and ISO 3746:2010 (survey, grade 3).
- sound_power_pressure(): per-band LW and A-weighted LWA from an
(NM, NB) level array over a hemisphere (radius) or parallelepiped
(dimensions + distance); surface area from the standard's closed forms
for 1/2/3 reflecting planes; energy average (Eq. 12), background K1
(Eq. 16), environmental K2 (Eq. A.2), apparent directivity index
(Eq. 7), expanded uncertainty.
- measurement_positions(): normative Annex B coordinates
(Tables B.1/B.2/B.3), grade- and plane-dependent subsets.
- background_noise_correction(): K1 with engineering/survey criteria.
- environmental_correction(): K2 from A, Sabine T+V, or alpha*Sv.
- SoundPowerResult (frozen dataclass), SoundPowerWarning.
Tests: 24 cases incl. monopole-over-plane exact LW recovery, radius
independence, K1/K2 closed forms, LWA via Annex E, and validations.
make check green (543 passed, 12 skipped); ruff/bandit/mypy --strict clean.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: directivity index under background correction, citation hygiene
Broadband K1 for the apparent directivity index was collapsing to the
surface-area term 10*lg(S/S0) (~+22 dB inflation with background
correction). Compute the true energy-based broadband K1 (per-band Eq. 16
aggregated over bands) so DI is correct in both paths.
Also: multi-band sound_power_level_a without frequencies now returns NaN
(A-weighting needs band centres); dropped PDF page-number citations from
Annex B/E table comments; corrected the survey parallelepiped position
citation to ISO 3746 clause C.1 / Figure C.7.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 3741 reverberation-room sound power
Add the ISO 3741:2010 precision (grade 1) methods for determining sound
power in a reverberation test room, in a new sound_power_reverberation
module:
- sound_power_reverberation() — direct method (Eq. 20): LW from the mean
room SPL and the Sabine equivalent absorption area A = (55,26/c)(V/T60),
with the full normative bracket: 10 lg(A/A0), 4,34*(A/S), the Waterhouse
boundary term 10 lg(1 + S c/(8 V f)), the reference-quantity (C1) and
radiation-impedance (C2) meteorological corrections and the -6 dB
constant. Speed of sound c = 20,05*sqrt(273 + theta).
- sound_power_comparison() — comparison method (Eq. 21) with a reference
sound source: LW = LW(RSS) + (Lp(ST) - Lp(RSS) + C2).
- ReverberationSoundPowerResult frozen dataclass; frequency-dependent
background correction K1 (Eq. 14, same formula as ISO 3744) with the
precision-grade 6/10 dB criteria; A-weighted total via Annex F.
Reuses the ISO 3744 energy-average and A-weighting helpers. Tests cover
exact inversion of Eq. (20), the Waterhouse term vanishing at high
frequency, the comparison method exact by construction, and synergy with
room_parameters T30 feeding the direct method.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 3741 room-qualification advisories and validation ordering
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 9614-2 sound power by intensity scanning
Add sound_power_intensity() computing per-band LW = 10lg(sum Pi/P0) from
per-segment signed normal intensity and areas (partial power Pi = <In,i>*Si),
the scanning-method field indicators FpI (Eq. A.1) and F+/- (Eq. A.2), the
repeatability criterion 3, and the achieved engineering/survey grade per band
(Annex B criteria 1-3). Negative total power flags bands as non-determinable
(clause 9.2); negative partial power raises SoundPowerWarning. Reuses
dynamic_capability_index for Ld = dpI0 - K (Table 1).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 16283-2 impact sound insulation and ISO 717-2 ratings
Add field impact sound insulation (ISO 16283-2, tapping machine) and the
ISO 717-2 single-number weighted impact rating with the CI spectrum
adaptation term, reusing the verified reference-curve shift engine.
- impact_insulation(li, t2, *, volume=None, t0=0.5): per-band
L'nT = Li - 10 lg(T/T0) (Formula (1)) and L'n = Li + 10 lg(A/A0) with
A = 0,16 V/T, A0 = 10 m2 (Formula (2)); positions energy-averaged.
- weighted_impact_rating(values_by_band, bands=None): Ln,w / L'n,w /
L'nT,w (Clause 4.3, octave -5 dB rule) and CI (Clause A.2.1, energetic
sum 100-2500 / 125-2000). Impact unfavourable deviations (measurement
exceeds reference, sign opposite to airborne) reduce to the airborne
search on negated curves, so _best_shift is reused verbatim.
- _best_shift: tolerance absorbs float noise at the exact bound (sums are
true multiples of 0,1 dB); airborne behaviour unchanged.
Verified against ISO 717-2 Annex C worked examples (Table C.1 Ln,w=79,
CI=-11; Table C.3 octave Ln,w=54, CI=0) and an independent brute-force
shift search on 10 000 random curves per band set. 2013 and 2020 editions
are identical for all implemented maths (2020 only adds Annex D rubber
ball, out of scope).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* feat: ISO 354 sound absorption in a reverberation room
Add phonometry.sound_absorption implementing BS EN ISO 354:2003:
- absorption_area(t60, volume, ...): equivalent sound absorption area
A = 55,3*V/(c*T) - 4*V*m (Eq. 5/7), speed of sound from Eq. (6).
- absorption_coefficient(t1, t2, volume, sample_area, ...): alpha_s =
(A2-A1)/S built from Eq. (8)/(9), per-measurement c1/c2, unclamped
(alpha_s > 1 valid, clause 3.7 NOTE 2); warns when T2 >= T1.
- attenuation_from_alpha: ISO-354 conversion m = alpha/(10 lg e) from an
ISO 9613-1 attenuation coefficient (m deferred to ISO 9613-1, default 0).
Composes directly with room_parameters() T20/T30 outputs. 25 tests
(exact T->A->T inversion, synthetic-alpha recovery, zero-m air term,
two-temperature Eq. (8), range validation, room_parameters synergy).
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: ISO 354 room and sample-size advisories
Add advisory AbsorptionWarning (never raising; result still returned) for
setup conditions outside ISO 354:2003 limits:
- Room volume below the 150 m3 minimum of clause 6.1.1, in both
absorption_area and absorption_coefficient.
- Sample area outside the clause 6.2.1.1 range 10 <= S <= 12 m2, with the
upper limit scaled by (V/200)^(2/3) when V > 200 m3, in
absorption_coefficient.
The volume advisory is emitted once by absorption_coefficient and suppressed
in its internal absorption_area calls to avoid duplicate warnings.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: deferred review minors — airborne brute-force net, advisory consistency, labels
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound power guide, impact and absorption sections, theory and API (EN)
Add a "Sound Power" guide covering the three LW routes (ISO 3744/3746
enveloping surface, ISO 3741 reverberation room with Waterhouse/C1/C2,
ISO 9614-2 intensity scanning), with a method-comparison table, executed
snippets and parameter tables. Extend the Room & Building Acoustics guide
with impact sound insulation (ISO 16283-2 + ISO 717-2, L'nT/L'n, tapping
machine, CI) and sound absorption in a reverberation room (ISO 354).
Add the matching theory sections (K1/K2, Waterhouse, C1/C2 derivations;
impact sign conventions; Sabine absorption) and API-reference rows for all
new public names. Update the landing standards count to 26, the sidebar,
README highlights/table, CHANGELOG and llms-full.txt.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: sound-power and impact figures and diagrams
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: include the sound-power guide in llms coverage
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: reposition Ln,w annotation in the impact figure
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* docs: gemelas ES de potencia sonora, impacto y absorción
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: final-review findings — comparison K1 reporting, citations, knee unification, docs attribution
- sound_power_comparison now reports the test-source K1 actually applied
per band (zero when no background), matching the dataclass docstring;
LW unchanged.
- Replace gitignored notes-iso3744-3746.md citation in the DI comment with
the standard reference (ISO 3744:2010, 3.24 / Eq. 7 context).
- Unify the K1 zeroing knee to the >= form (ΔLp >= 15 -> no correction).
- Broaden SoundPowerWarning docstring to name all emitters (ISO 3744/3746,
ISO 3741, ISO 9614-2).
- Fix docs misattributing K2 to ISO 3741 (ISO 3744 K2 vs ISO 3741 absorption
term) across EN/ES room-acoustics guides.
- EN impact-setup diagram uses dot decimals (0.16); regenerate the 4 variants.
- CHANGELOG: label the ISO 717-2 Annex C value Ln,w = 79.
- Warn-after-validate in sound_power_comparison; "is raised" -> "is emitted".
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 review round 1 — per-band DI and K2, sweep-reversal repeatability, validation and broadcast ergonomics
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
* fix: PR 84 round 2 — partial room-data validation, result-field docs
Raise a clear ValueError in environmental_correction (and its
sound_power_pressure pass-through) when exactly one member of a
room-data pair (reverberation_time/room_volume or
mean_absorption_coefficient/room_surface) is supplied, instead of
silently returning K2=0 as if free field. All-None remains the
legitimate free-field K2=0 path.
Document frequencies on the ReverberationSoundPowerResult row and
negative_band as a standalone per-band boolean field on the
SoundPowerIntensityResult row across docs/api-reference.md and the
EN/ES site twins.
Claude-Session: https://claude.ai/code/session_013kkVt3nxi9svp1an28uHxf
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.
Align Spanish acoustics terminology to UNE-EN wording in figures (#256)
* fix(es): align Spanish acoustics terminology to UNE-EN wording in figures
I correct three Spanish terms in the figure and diagram generators so they
match the official UNE-EN wording already used by the .plot() string tables:
"reducción sonora" becomes "reducción acústica" (sound reduction index R,
UNE-EN ISO 717-1), "reducción vibracional" becomes "reducción de
vibraciones" (vibration reduction index Kij, UNE-EN ISO 10848), and
"potencia sonora" becomes "potencia acústica" (sound power level LW,
UNE-EN ISO 3740 series).
I regenerate the affected Spanish SVG figures with make graphs so the
committed images match the corrected wording, and update the Spanish guide
prose that describes those figures and the underlying concepts to use the
same terminology, fixing one now-stale anchor link along the way.
* fix(es): catch markup-split terms, escaped-unicode figures and revert an over-application
I catch a few gaps the first pass missed. Two figure title/label strings
in generate_graphs.py store their accents as Python \u escapes rather than
literal characters ("reducción sonora"), so my plain-text sed never
matched them; I correct both and regenerate insulation_rating_es and
insulation_uncertainty_demo_es. I also fix a handful of guide-prose
occurrences the earlier sed missed because bold markup or a line wrap
split the phrase across "potencia **X** sonora" or "reducción\nsonora",
and I repoint one anchor link at the new heading slug.
I also revert an over-application: "potencia sonora estructural" (EN
15657's structure-borne power, a distinct quantity from the airborne
ISO 3740 sound power that "potencia acústica" refers to) got swept up by
the earlier global replace. I restore "sonora" there across the generator,
the figure and the guide prose, and fix a "vibroacústica" word that got
split apart by the revert.