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; removeScene,ISMSimulator,RIRSimulator,simulate_rir,simulate_dynamic_rir,split_directivity, per-call tensor settings, and backend injection - models: remove the redundant public
SceneLikealias; APIs spell outStaticScene | DynamicScenedirectly - config: require a complete, keyword-only
SimulationConfigat construction: exactly one ofmax_order/nb_imgand exactly one oftmax/nsamplemust be present; normalizenb_imgto an immutable tuple - config: remove
fs,mixed_precision,directivity,rir_hpf_enable,rir_hpf_fc,rir_hpf_kwargs,rir_hpf, anddefault_config; remove the redundant publicvalidate()methods andRIRHighPassConfig.as_scipy_kwargs; room sampling rate and endpoint directivity now belong exclusively to the scene - config: restrict RIR simulation to
torch.float32andtorch.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
directivitytoSourceandMicrophoneArray; 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(...); removeenabled, renamerp/rs/filter_typetopassband_ripple_db/stopband_attenuation_db/filter_family, and add explicitphase; the default simulation no longer performs a hidden SciPy/CPU post-processing pass - packaging: move SciPy from the core installation to the optional
hpfextra 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_filterpolicy instead of carrying an incomplete compatibility implementation - packaging: declare the setuptools build backend and src-layout discovery
explicitly; add a
cliextra 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
RIRResulttorirs,scene, andResolvedSimulationConfig; the frame schedule is read from a dynamic scene and the diffuse seed from the resolved config, while the redundantbackendlabel 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 anddataclasses.replacevalidate 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()andDynamicScene.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 requiredtime_reference="emission" | "observation"and aFrameSchedule; remove implicit equal partitioning for raw RIR tensors - models: remove
DynamicScene.timestamps;DynamicScene.scheduleis 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, andfixed_hopas 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.startsreturn a mutation-safe CPUint64snapshot, preventing callers from invalidating a schedule after construction - geometry: replace
linear_trajectory(start, end, steps)withlinear_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 intermediateint64product ortorch.arangeendpoint - signal: make both
convolve_rirandDynamicConvolveralways return(microphones, samples); a single microphone is no longer squeezed to one dimension - io: remove top-level
torchrir.load/save, ambiguoustorchrir.io.load/save/info, datasetload/savere-exports, the process-globalAudioBackend,list_audio_backends,get_audio_backend,set_audio_backendregistry, and allbackend=/format=overrides; canonical*_audio,AudioData, and extension-checked*_wavAPIs remain; all save entry points now preserve gain by default (normalize=False). WAV output with no explicit subtype usesFLOAT; integer/companded subtypes reject samples outside[-1, 1]before SoundFile can clip them silently - io: make
AudioDataandAudioInfofrozen, 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.Paththe 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.sceneversion 1. The canonical top-level fields areschema,generator,room,sources,mics,trajectories,rir,doa,frame_schedule,signal,convolution, anddynamic(plussimulation,source_info, andextrawhen applicable). Remove duplicated array descriptions, the completetime_axissample list, second-domainstarts_seconds, and other derived copies;rirnow records its sample axis compactly as origin, count, and sample rate - metadata: replace the
timestampsarguments ofbuild_metadataandsave_scene_metadatawith exactscheduleand explicittime_reference; add the same schedule/time-reference contract tobuild_result_metadataandsave_result_metadata, with no compatibility argument - datasets: make
DatasetItemandCollateBatchfrozen, slotted, keyword-only, identity-comparing records; add an explicit per-itemmetadatafield, normalize batch metadata sequences to tuples, and require validated finite mono floating-point audio instead of deferring malformed tensors to padding failures - datasets: make
BaseDatasetan abstract interface and makeCmuArcticSentence,LibriSpeechSentence, andDatasetAttributionfrozen, 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, ...)tochoose_speakers(speakers, ...)and require an explicitspeakers=catalog inload_dataset_sources; the factory now receives only selected string IDs and is never called with a hiddenNonesentinel. Addcmu_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;
--downloadis 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 contractbuild_dynamic_cmu_arctic(DynamicCmuArcticBuildConfig) -> DynamicDatasetBuildResult; validated staged publication with rollback now belongs to that canonical builder;DynamicCmuArcticBuildConfigowns onesimulation=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
NotImplementedErrorinstead of falling back to pathname checks or non-atomic replacement without the required POSIXdir_fd,O_NOFOLLOW, and atomic no-replace/exchange primitives - util: remove public
infer_device_dtype; device and dtype resolution now goes throughDeviceSpecandresolve_device, both restricted to supported CPU, CUDA, and MPS execution;DeviceSpecis 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
LoggingConfiga frozen, slotted, keyword-only record; remove configurable logger names and propagation, validate level/format/date fields at construction, and makesetup_logging(config)configure only the non-propagatingtorchrirnamespace 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
int64frame starts the only stored scheduling unit.FrameSchedule.from_secondsperforms the solefloor(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-negativeint64domain; unrepresentable second values and sample rates now raise stable publicValueErrors 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 withTypeError, bound audio/dataset sample rates to1..2**31-1, and enforce positive/non-negativeint64domains 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 promotefloat16/bfloat16internally tofloat32for 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
TypeErrorinstead 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=1endpoints 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_distanceinstead of clamping the singular1 / rgain - sim: stream L1-order and rectangular image-source indices in bounded
image_chunk_sizebatches instead of materializing a complete meshgrid; compute the requested image count analytically and reject axis widths or totals that exceedint64before enumeration - sim: make finite
float64extreme geometry numerically stable across static, batched, and dynamic paths: scale the affine image-position formula, vector norms, and directivity normalization; scalefs / cby bounded binary exponents; and reject final unrepresentable images or attenuations. Delays outside the usable sample domain are masked before anyint64cast, 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**2in 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, andfloat64on CPU/CUDA/MPS; make explicitdevice="auto"choose CUDA, then compatible MPS, then CPU; reject MPS+float64 before execution, and letdevice=None/dtype=Noneinherit 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 disablestorch.compile - metadata: classify
DynamicSceneby its explicit type rather than frame count, preserving trajectories anddynamic=truefor one-frame scenes; record microphone layout assingleorcustomwith 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 withhypot, preserving finite values for extremefloat64coordinates - metadata: distinguish non-integer
signal_lentype errors from non-positive values, enforce the documented mapping contract forextra, and preserve an explicitly supplied emptyextra={}instead of treating it as absent - metadata: require recursive
source_info/extrapayload 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
int64domain; reject cross-platform-unsafe output filenames, malformed attribution/modification lines, and logger objects without a callableinfomethod before creating output directories. Attribution files now honorattribution_required=false - logging: update the TorchRIR-managed handler's level and formatter on
repeated
setup_loggingcalls, and treat only the exacttorchrirnamespace (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.
RIRResultsnapshots 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.betawithreshape; giveFrameSchedulea 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 -mrunpy 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_sourcesinputs, 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;downloadandkeep_metadatanow 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 withdir_fdandO_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
.partpath. Require an optionalContent-Lengthto 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_NOFOLLOWdescriptor - 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.sndaliases to explicit SoundFile containers when saving - io: normalize
AudioInfosample rate, frame count, and channel count from Python/NumPy integers; bound frames to non-negativeint64, channels to positiveint32, and sample rate to1..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_dataaccept 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.deviceobjects with the same CPU/CUDA/MPS resolver used for strings; unsupportedmeta/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*piamplitude 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
mainon Read the Docs through an explicit custom build, and remove the GitHub Pages deployment path and the obsoletetaishi.org/torchrirlinks
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