Skip to content

Changelog

This file is generated by Commitizen during release.

v1.0.0 (2026-07-22)

Breaking changes

  • sim: reduce the public simulation API to simulate(StaticScene | DynamicScene, SimulationConfig) -> RIRResult; remove Scene, ISMSimulator, RIRSimulator, simulate_rir, simulate_dynamic_rir, split_directivity, per-call tensor settings, and backend injection
  • models: remove the redundant public SceneLike alias; APIs spell out StaticScene | DynamicScene directly
  • config: require a complete, keyword-only SimulationConfig at construction: exactly one of max_order/nb_img and exactly one of tmax/nsample must be present; normalize nb_img to an immutable tuple
  • config: remove fs, mixed_precision, directivity, rir_hpf_enable, rir_hpf_fc, rir_hpf_kwargs, rir_hpf, and default_config; remove the redundant public validate() methods and RIRHighPassConfig.as_scipy_kwargs; room sampling rate and endpoint directivity now belong exclusively to the scene
  • config: restrict RIR simulation to torch.float32 and torch.float64; explicit or inherited float16/bfloat16 geometry is rejected before the ISM kernel because its position, distance, delay, and gain calculations are not numerically safe at those precisions. Signal convolution continues to accept float16/bfloat16 through float32 work buffers
  • models: add directivity to Source and MicrophoneArray; a non-omni endpoint must carry its own orientation, so geometry and acoustic endpoint properties cannot disagree with a separate simulation setting
  • config: make RIR high-pass filtering opt-in through high_pass=RIRHighPassConfig(...); remove enabled, rename rp/rs/ filter_type to passband_ripple_db/stopband_attenuation_db/ filter_family, and add explicit phase; the default simulation no longer performs a hidden SciPy/CPU post-processing pass
  • packaging: move SciPy from the core installation to the optional hpf extra because the only SciPy-dependent operation is now opt-in
  • packaging: raise the Python floor from 3.11.0 to 3.11.4 so archive extraction can require the standard-library tarfile.data_filter policy instead of carrying an incomplete compatibility implementation
  • packaging: declare the setuptools build backend and src-layout discovery explicitly; add a cli extra for advertised YAML configuration support and publish repository, documentation, and changelog URLs in package metadata
  • sim: change the returned RIR from the former causal, FIR-delayed axis to the physical propagation-time sample axis; with the default 81-tap filter this moves arrivals 40 samples earlier, centers interpolation taps directly at physical arrival samples, and clips support outside the requested interval
  • results: reduce RIRResult to rirs, scene, and ResolvedSimulationConfig; the frame schedule is read from a dynamic scene and the diffuse seed from the resolved config, while the redundant backend label is removed; requested settings are resolved once before the kernel and the same immutable object is stored with the result
  • config: remove public ResolvedSimulationConfig.from_config; runtime resolution is now an internal simulation step, while direct construction and dataclasses.replace validate every resolved invariant
  • models: make room, endpoint, scene, result, schedule, and configuration records slotted and keyword-only where they have generated constructors; remove unused StaticScene.is_dynamic() and DynamicScene.is_dynamic()
  • models: normalize endpoint orientation to canonical unit vectors with shape (entities, dimensions); 2D per-entity angles now require (n, 1), while a flat length-two value unambiguously means one shared direction vector
  • models: require room, source, microphone, and Tensor trajectory geometry to have one device and dtype; tensor-like trajectory sequences inherit their endpoint layout, but Tensor inputs are no longer silently cast at scene construction
  • signal: replace DynamicConvolver(mode=..., hop=..., timestamps=..., fs=...) with a required time_reference="emission" | "observation" and a FrameSchedule; remove implicit equal partitioning for raw RIR tensors
  • models: remove DynamicScene.timestamps; DynamicScene.schedule is now the optional, authoritative sample-domain time axis. A result consumes that scene schedule automatically, while a raw RIR tensor or a result whose scene has no schedule requires a call-level schedule. Supplying both is rejected
  • signal: add FrameSchedule.from_samples, from_seconds, uniform, and fixed_hop as explicit frame-boundary constructors; fixed-hop schedules must match the RIR frame count exactly, and observation-time schedules may update the receiver during the convolution tail
  • signal: store frame starts immutably and make FrameSchedule.starts return a mutation-safe CPU int64 snapshot, preventing callers from invalidating a schedule after construction
  • geometry: replace linear_trajectory(start, end, steps) with linear_trajectory(start, end, *, progress=...); interpolation now consumes an explicit normalized grid instead of inventing an endpoint-inclusive time axis. FrameSchedule.normalized_progress(...) derives the canonical grid from exact integer frame starts without low-precision integer overflow and prevents dtype rounding from turning the last pre-endpoint start into the endpoint itself; it rejects requested dtypes that collapse distinct starts to one progress value. Uniform/fixed-hop schedules use Python integer arithmetic so long timelines cannot overflow an intermediate int64 product or torch.arange endpoint
  • signal: make both convolve_rir and DynamicConvolver always return (microphones, samples); a single microphone is no longer squeezed to one dimension
  • io: remove top-level torchrir.load/save, ambiguous torchrir.io.load/save/info, dataset load/save re-exports, the process-global AudioBackend, list_audio_backends, get_audio_backend, set_audio_backend registry, and all backend=/format= overrides; canonical *_audio, AudioData, and extension-checked *_wav APIs remain; all save entry points now preserve gain by default (normalize=False). WAV output with no explicit subtype uses FLOAT; integer/companded subtypes reject samples outside [-1, 1] before SoundFile can clip them silently
  • io: make AudioData and AudioInfo frozen, slotted, and keyword-only; require real finite non-empty audio, a positive integer sample rate, positive channel counts, valid frame/duration metadata, non-empty format/subtype names, boolean normalization, and non-empty explicit save subtypes
  • io: make pathlib.Path the only pathname type accepted by audio entry points; load functions additionally accept an already-open seekable binary stream, leave caller-owned streams open, and reject string paths, closed streams, and non-seekable objects at the public boundary
  • metadata: replace the legacy, redundant metadata layout with schema torchrir.scene version 1. The canonical top-level fields are schema, generator, room, sources, mics, trajectories, rir, doa, frame_schedule, signal, convolution, and dynamic (plus simulation, source_info, and extra when applicable). Remove duplicated array descriptions, the complete time_axis sample list, second-domain starts_seconds, and other derived copies; rir now records its sample axis compactly as origin, count, and sample rate
  • metadata: replace the timestamps arguments of build_metadata and save_scene_metadata with exact schedule and explicit time_reference; add the same schedule/time-reference contract to build_result_metadata and save_result_metadata, with no compatibility argument
  • datasets: make DatasetItem and CollateBatch frozen, slotted, keyword-only, identity-comparing records; add an explicit per-item metadata field, normalize batch metadata sequences to tuples, and require validated finite mono floating-point audio instead of deferring malformed tensors to padding failures
  • datasets: make BaseDataset an abstract interface and make CmuArcticSentence, LibriSpeechSentence, and DatasetAttribution frozen, slotted, keyword-only records with canonical identifier and field validation; positional record construction and incomplete dataset subclasses are no longer accepted
  • datasets: change choose_speakers(dataset, ...) to choose_speakers(speakers, ...) and require an explicit speakers= catalog in load_dataset_sources; the factory now receives only selected string IDs and is never called with a hidden None sentinel. Add cmu_arctic_speakers(root) for usable local-speaker discovery while the no-argument form continues to enumerate the supported catalog
  • examples: remove the dynamic-dataset script's implicit retry with downloading enabled; --download is now the sole authorization for network access, matching the dataset loader contract
  • datasets: replace build_dynamic_cmu_arctic_dataset(**kwargs) with the single config/result contract build_dynamic_cmu_arctic(DynamicCmuArcticBuildConfig) -> DynamicDatasetBuildResult; validated staged publication with rollback now belongs to that canonical builder; DynamicCmuArcticBuildConfig owns one simulation=SimulationConfig(...) instead of duplicating RIR length, order, device, and dtype settings
  • datasets: require Linux or macOS for secure corpus filesystem access, archive transfer/extraction, locking, and staged publication. Unsupported platforms or filesystems now raise NotImplementedError instead of falling back to pathname checks or non-atomic replacement without the required POSIX dir_fd, O_NOFOLLOW, and atomic no-replace/exchange primitives
  • util: remove public infer_device_dtype; device and dtype resolution now goes through DeviceSpec and resolve_device, both restricted to supported CPU, CUDA, and MPS execution; DeviceSpec is now slotted and keyword-only
  • validation: standardize finite-real parameters used by simulation configuration, rooms/acoustics, geometry, frame-time conversion, audio, and dataset utilities. Booleans, numeric strings, and scalar Tensors are no longer coerced, and integers outside finite float range now fail at the public boundary
  • logging: make LoggingConfig a frozen, slotted, keyword-only record; remove configurable logger names and propagation, validate level/format/date fields at construction, and make setup_logging(config) configure only the non-propagating torchrir namespace root
  • docs: remove the compatibility-oriented 0.9 migration page; this changelog is the permanent record of removed APIs and numerical changes
  • experimental: remove ray-tracing, FDTD, and template-dataset placeholder classes that could only warn and raise NotImplementedError; planned features remain roadmap items until an executable contract exists

Fixed and changed

  • signal: distinguish source emission time from microphone observation time in dynamic convolution, reject motion/time-reference mismatches when scene metadata is available, and reject simultaneous source and microphone motion because it requires a two-time retarded-propagation kernel
  • signal: make CPU int64 frame starts the only stored scheduling unit. FrameSchedule.from_seconds performs the sole floor(time * sample_rate) conversion and retains the conversion sample rate as provenance; attaching such a schedule to a room or result with a different sampling rate now fails instead of silently changing boundaries. Starts, endpoints, and derived samples must fit the non-negative int64 domain; unrepresentable second values and sample rates now raise stable public ValueErrors instead of leaking float-conversion overflow
  • validation: normalize public integer counts, indices, sample rates, and seeds from non-boolean Python/NumPy integer scalars to Python int; reject fractional values and booleans with TypeError, bound audio/dataset sample rates to 1..2**31-1, and enforce positive/non-negative int64 domains where later tensor or sample arithmetic requires them
  • signal: batch source/microphone FFT convolution, preserve autograd on the CUDA dynamic-emission path by avoiding out= FFT writes, and promote float16/bfloat16 internally to float32 for FFT, source summation, and emission overlap-add or observation-time frame selection before one final cast to the requested dtype; split highly uneven adjacent emission frames adaptively so padding waste cannot grow with the fixed batch width
  • signal: validate the supported real dtype set at every public tensor boundary so unsupported float8 formats fail deterministically before FFT, SoundFile, padding, or simulation kernels; non-Tensor convolution payloads now raise a direct TypeError instead of leaking attribute errors
  • geometry: align every dynamic example's geometry frame with schedule.starts[i] / stop_sample; the previous endpoint-inclusive helper applied the nominal endpoint about one frame too early and held it through the final interval (and, for moving microphones, the convolution tail)
  • geometry: reject empty, complex, and boolean trajectory endpoints with explicit errors instead of returning empty paths or silently discarding imaginary components; evaluate linear interpolation as a convex combination so finite extreme endpoints cannot overflow their difference and exact progress=0/progress=1 endpoints remain exact
  • geometry: validate array and sampling counts, dimensions, planes, random generators, margins, distances, ranges, and attempts before tensor kernels; flatten a single-row direction or normal consistently with a flat vector; normalize extreme direction vectors through max-absolute-value scaling so their finite Euclidean norm does not overflow a raw sum of squares
  • sim: require sources, microphones, and every trajectory frame to lie strictly inside the room; reject source--microphone distances below min_source_mic_distance instead of clamping the singular 1 / r gain
  • sim: stream L1-order and rectangular image-source indices in bounded image_chunk_size batches instead of materializing a complete meshgrid; compute the requested image count analytically and reject axis widths or totals that exceed int64 before enumeration
  • sim: make finite float64 extreme geometry numerically stable across static, batched, and dynamic paths: scale the affine image-position formula, vector norms, and directivity normalization; scale fs / c by bounded binary exponents; and reject final unrepresentable images or attenuations. Delays outside the usable sample domain are masked before any int64 cast, avoiding wraparound and invalid lookup-table indexing
  • directivity: require a supported finite floating Tensor cosine in [-1, 1] and clamp internally computed extreme-direction roundoff to that analytic interval before evaluating a pattern
  • acoustics: use dimension-specific Sabine constants and the room speed of sound, and reject T60 values that require absorption above one instead of silently clipping them; reject target T60 values whose pressure-reflection coefficient collapses to exactly zero or one at the requested room dtype, and evaluate 1 - beta**2 in a cancellation-resistant scalar form
  • sim: join diffuse tails from the preceding 10 ms RMS with a 5 ms power-complementary crossfade, use the room's actual speed of sound when estimating decay, and seed one source--microphone carrier so results are invariant to requested horizon and unrelated batch composition. Dynamic frames share that carrier while retaining frame-specific RMS levels; infinite T60 remains non-decaying, and zero-time or zero-energy handoffs are rejected; compute handoff RMS with max-absolute-value scaling, guard extreme sample-time products against overflow, and reject an unrepresentable completed tail
  • sim: keep causal and zero-phase HPF operations as explicit opt-in phase choices; causal filtering preserves prefix invariance, while zero-phase filtering is documented as finite-length, non-causal processing
  • config: validate filter-family-specific HPF parameters: Chebyshev-I and elliptic filters require positive passband ripple, Chebyshev-II and elliptic filters require positive stopband attenuation, and elliptic attenuation must exceed its ripple
  • device: limit generic tensor/convolution dtype resolution to float16, bfloat16, float32, and float64 on CPU/CUDA/MPS; make explicit device="auto" choose CUDA, then compatible MPS, then CPU; reject MPS+float64 before execution, and let device=None/dtype=None inherit only from mutually consistent input tensors
  • config: record effective rather than merely requested execution settings in RIRResult.config: MPS disables the sinc LUT and CPU disables torch.compile
  • metadata: classify DynamicScene by its explicit type rather than frame count, preserving trajectories and dynamic=true for one-frame scenes; record microphone layout as single or custom with its center and minimum pair distance, exact schedule starts in samples, optional signal dimensions, and optional emission/observation convolution dimensions
  • metadata: validate that recorded emission/observation time agrees with source/microphone motion, reject simultaneous endpoint motion consistently with DynamicConvolver, and compute direction-of-arrival values on CPU in float64 so half/bfloat geometry does not quantize angles; compute microphone centers with coordinate scaling, minimum pair distances with a stable vector norm, and DOA horizontal distance with hypot, preserving finite values for extreme float64 coordinates
  • metadata: distinguish non-integer signal_len type errors from non-positive values, enforce the documented mapping contract for extra, and preserve an explicitly supplied empty extra={} instead of treating it as absent
  • metadata: require recursive source_info/extra payload containers to be acyclic and use string mapping keys, real numbers, and finite floating values; normalize JSON-representable NumPy scalar/array values without recursive scalar conversion. Tensor payloads must be materializable dense-strided values on CPU/CUDA/MPS, with complex, sparse, nested, quantized, unsupported-device, and unsupported floating-dtype tensors rejected
  • metadata: include the TorchRIR distribution version and PyTorch version in generator; write JSON atomically with non-finite values forbidden and preserve the permission mode when replacing an existing file
  • metadata: require signal and convolution-output sample counts to fit the positive int64 domain; reject cross-platform-unsafe output filenames, malformed attribution/modification lines, and logger objects without a callable info method before creating output directories. Attribution files now honor attribution_required=false
  • logging: update the TorchRIR-managed handler's level and formatter on repeated setup_logging calls, and treat only the exact torchrir namespace (not arbitrary names sharing that character prefix) as already qualified; serialize handler creation/update and remove duplicate managed handlers
  • models: revalidate shallow-mutable room, reflection, endpoint, orientation, trajectory, schedule, device, and dtype tensor invariants at simulation and metadata/convolution consumption boundaries. RIRResult snapshots every scene tensor and compares both identity and value, including shared NumPy storage and inference tensors without version counters; it also rescans RIR finiteness whenever a convolver or metadata writer consumes the result
  • models: use identity equality for Tensor-carrying model records instead of dataclass field equality, which could raise an ambiguous-Tensor-bool exception; flatten non-contiguous Room.beta with reshape; give FrameSchedule a bounded representation with starts, frame count, and seconds-conversion provenance
  • datasets: make dynamic build config/result records keyword-only and slotted; normalize Paths and sequence fields to immutable snapshots, and fail locally decidable invalid configs (including T60 feasibility and image-grid dimension) before creating a staging directory
  • datasets: lazy-load the executable dynamic builder from the package namespace, avoiding eager module execution and the resulting python -m runpy warning while retaining the canonical package-level function
  • datasets: set dynamic CMU ARCTIC defaults to 256 trajectory frames and SimulationConfig(max_order=6, nsample=4096, dtype=torch.float32); derive trajectory positions from the exact integer frame schedule rather than a different endpoint-inclusive time grid
  • datasets: reject any overlap between the source corpus and output roots before staging, and scale all reverberant stems with one shared factor that also constrains their summed mixture; save stems and mixture as 32-bit float WAV to preserve relative gains and additivity
  • datasets: convert requested duration with ceil(duration_sec * sample_rate), use that effective sample-aligned duration for motion, and record requested and effective durations in metadata
  • datasets: validate load_dataset_sources inputs, unique speakers, every loaded utterance, and common sample rate/dtype/device; use the same ceiling rule for fixed-duration source loading and prevent empty or multichannel audio from entering concatenation
  • datasets: validate every dynamic-builder utterance sample rate, require trajectory_steps <= ceil(duration_sec * sample_rate), and sample microphone/source geometry from strict room interiors rather than closed wall boundaries
  • datasets: switch CMU ARCTIC downloads to HTTPS, pin all CMU SHA-256 and LibriSpeech MD5 archive checksums, validate canonical utterance/speaker paths, and extract only regular files/directories while rejecting traversal, links, FIFOs, and device nodes
  • datasets: treat missing and partial local trees uniformly as incomplete; require every scanned non-empty transcript entry in a tree counted as ready to parse canonically and at least one canonical ID to have a matching regular audio file, skip archive/network work for an already usable tree, and extract into a validated staging directory before replacing an incomplete target, restoring the previous tree if publication fails. Archive extraction combines the manual path/member allowlist with the standard-library tarfile.data_filter; download and keep_metadata now require actual booleans. A requested LibriSpeech speaker is checked directly, so another usable speaker can no longer suppress repair of a partial subset; dataset/subset roots, intermediate corpus directories, and final transcript/audio symlinks are rejected. Walk every component from an opened root with dir_fd and O_NOFOLLOW, and consume transcripts/audio through that same final descriptor so validation and parsing/decoding cannot target different inodes. LibriSpeech transcript IDs must additionally agree with their numeric speaker/chapter directories, and transcript-like files outside usable trees are ignored
  • datasets: centralize verified archive transfers with a 60-second per-connect/per-read timeout, a six-hour total network-transfer deadline, a 64 GiB response limit, and exclusively created marker-owned sibling workspaces that never reuse or follow a fixed .part path. Require an optional Content-Length to be a valid non-negative value within the limit and to match the complete body through EOF; always require the pinned digest. Retry once by default only for HTTP 408/429/5xx, connection/body transport, malformed/short/overlong response length, or digest-integrity failures; propagate other HTTP statuses and local filesystem, extraction, validation, and publication failures without re-downloading a verified archive
  • datasets: publish a verified archive to an absent name with atomic no-replace, or replace an existing regular file/symlink with atomic exchange/swap plus a device/inode/type comparison. Reverse the exchange and retain a racing third-party entry on identity mismatch; never follow a symlink target, and reject other non-regular cache entries. Digest verification and tar parsing share one unchanged O_NOFOLLOW descriptor
  • datasets: prevalidate the complete tar member list before writing, allowing only contained regular files/directories and bounding member count, per-file size, and total declared content. Isolate extracted payloads from workspace ownership metadata; under the corpus writer lock, reclaim stale marker-owned download/extraction workspaces while leaving unsafe or unowned paths untouched, and report cleanup failures without hiding the primary operation result
  • datasets: serialize corpus repair per CMU speaker or LibriSpeech subset; the writer lock covers stale-workspace cleanup, readiness, cache handling, download, extraction, validation, and publication. A separate per-target publication lock covers only transaction recovery and the final target check, rename, rollback, and cleanup. Enforce the lock's finite deadline before and after non-blocking acquisition, and revalidate the locked path/inode to avoid split-brain writers
  • datasets: serialize the complete dynamic build for one output target with .<target>.torchrir-build.lock, acquired before recovery, existence checks, stale marker-owned build-workspace cleanup, corpus loading, and scene generation. Continue to use the narrower nested publication lock for commit, so competing same-target builders do not duplicate expensive work while different targets remain independent
  • datasets: persist a fsynced publication manifest containing staged and previous directory device/inode identities plus transaction phase; use platform atomic no-replace renames for create, backup, publish, and rollback. Recover or clean only identities recorded in the manifest, preserve the backup on a third-party target, changed identity, unsafe symlink, malformed manifest, or unknown transaction entry, and distinguish a rename that completed before reporting an error from one that did not
  • io: reject zero-channel audio before SoundFile import, inherit a loaded subtype only when saving to the same container format, and otherwise let the destination choose a valid default; resolve .wave, .aif, .aifc, .oga, and .snd aliases to explicit SoundFile containers when saving
  • io: normalize AudioInfo sample rate, frame count, and channel count from Python/NumPy integers; bound frames to non-negative int64, channels to positive int32, and sample rate to 1..2**31-1; report malformed metadata types separately from invalid values
  • io: normalize audio in float64 before narrowing to its SoundFile storage dtype, reject peaks or unnormalized samples that the destination float dtype cannot represent, and recheck finiteness before any file write
  • io: read audio metadata and samples through one SoundFile descriptor; load_audio/load_audio_data accept caller-owned seekable binary streams without closing them, allowing dataset loaders to validate and decode the exact same opened inode instead of checking a path and reopening it
  • device: validate inferred Tensor devices and torch.device objects with the same CPU/CUDA/MPS resolver used for strings; unsupported meta/XPU layouts no longer bypass the public device contract, including trajectory progress materialization
  • tensor contracts: reject sparse, nested, quantized, or meta tensors at schedule, trajectory, convolution, simulation-result, and metadata boundaries before shape conversion or backend kernels can leak internal exceptions
  • packaging: publish the Apache-2.0 license expression and include this changelog in source distributions; CI verifies both artifact contracts, consumes the committed lockfile, and strict-builds documentation on pull requests

Verification

  • tests: add independent analytic, boundary, and metamorphic tests plus pinned pyroomacoustics 0.9.0 and rir-generator 0.3.0 comparisons
  • tests: treat external implementations as supporting evidence rather than unconditional oracles; gpuRIR comparisons account for reported upstream issues, restrict RIR parity to direct paths, and isolate trajectory convolution with identical synthetic RIR tensors
  • tests: use only predetermined reference transforms: pyroomacoustics' fixed 40-sample fractional-delay offset and the documented 4*pi amplitude normalization for gpuRIR/rir-generator; no waveform is freely aligned
  • tests: verify static and both dynamic convolution conventions retain autograd on CPU, and compare dynamic-emission outputs plus signal/RIR gradients against CPU on CUDA/MPS representative paths; unexpected warnings remain errors except for narrowly matched upstream MPS FFT warnings
  • tests: add double-precision gradcheck coverage for observation time and a nine-frame emission path that crosses the adaptive batch boundary

Cached RIRs and code that relies on removed APIs, the former delayed time axis, the previous default HPF, timestamp-based or implicit dynamic schedules, the legacy metadata schema, implicit save normalization, or squeezed mono outputs must be regenerated or updated. No compatibility or migration mode is retained.

Docs

  • publish the Zensical documentation from main on Read the Docs through an explicit custom build, and remove the GitHub Pages deployment path and the obsolete taishi.org/torchrir links

v0.9.2 (2026-07-22)

Fix

  • sim: correct critical reflected source-directivity gains
  • sim: versions v0.1.0 through v0.9.1 evaluated image-source reflections with the unmirrored physical source orientation, producing physically incorrect gains and potentially incorrect polarity for signed patterns
  • sim: mirror source orientation across every wall with odd reflection parity in static, batched, and dynamic ISM paths
  • sim: direct sound, omnidirectional sources, and microphone-only directivity were unaffected
  • sim: users of cardioid, subcardioid, hypercardioid, or bidirectional source patterns should regenerate RIRs produced by affected releases

v0.9.1 (2026-07-21)

Docs

  • migrate the documentation toolchain, local commands, CI, and remote deployment from MkDocs/Read the Docs to strict Zensical builds on GitHub Pages; remove the obsolete Read the Docs configuration

v0.9.0 (2026-07-21)

Feat

  • core: unify scene simulation and harden public api contracts

v0.8.1 (2026-02-18)

Fix

  • tests: resolve ty type errors in annotation assertions

v0.8.0 (2026-02-18)

Feat

  • datasets: migrate dynamic CMU ARCTIC builder and enhance viz outputs

v0.7.1 (2026-02-12)

v0.7.0 (2026-02-12)

Feat

  • datasets: centralize attribution metadata and example output notices

Fix

  • docs: switch readthedocs build to mkdocs

v0.6.3 (2026-02-11)

Fix

  • enforce simulator config conflicts and scene validation behavior

Refactor

  • split scene models and reorganize io interfaces

v0.6.2 (2026-02-10)

Refactor

  • harden core design invariants and runtime interfaces

v0.6.1 (2026-02-10)

Fix

  • align docs/api examples and remove unused symbols

Refactor

  • normalize module headers and stabilize CI quality gates

v0.6.0 (2026-02-10)

Feat

  • sim: support nb_img for dynamic RIR comparisons

v0.5.2 (2026-02-10)

v0.5.1 (2026-02-10)

v0.5.0 (2026-02-10)

Feat

  • add pyroomacoustics-style rir hpf and update comparison docs

v0.4.2 (2026-02-05)

Feat

  • update example plotting outputs
  • examples: write GIFs with plot
  • examples: add dataset auto-download and mic count
  • examples: unify dynamic dataset builder
  • examples: enforce min source distance
  • examples: allow partial moving sources
  • examples: constrain source heights

Fix

  • examples: write all dynamic dataset scenes

Refactor

  • rename non-pythonic APIs

v0.4.1 (2026-02-05)

v0.4.0 (2026-02-05)

Refactor

  • add io backends and info api
  • use explicit non-wav audio helpers
  • slim top-level io exports
  • split logging and config modules
  • sim: route sim and signal functions via modules
  • signal: move signal APIs under torchrir.signal
  • datasets: import datasets from torchrir.datasets

v0.3.1 (2026-02-05)

v0.3.0 (2026-02-05)

Feat

  • add LibriSpeech dynamic dataset example

Refactor

  • move array geometries into MicrophoneArray

v0.2.0 (2026-02-05)

Feat

  • add DataLoader collate helper
  • add LibriSpeech dataset and shared audio loader

Perf

  • batch dynamic ISM across time

v0.1.4 (2026-02-05)

v0.1.2 (2026-02-05)

v0.1.1 (2026-02-04)

v0.1.0 (2026-02-04)