Documentation
¶
Overview ¶
Package sofa provides reading and writing support for SOFA files (Spatially Oriented Format for Acoustics, AES69).
SOFA is a file format for storing spatially oriented acoustic data like head-related transfer functions (HRTFs), binaural room impulse responses (BRIRs), and directional room impulse responses (DRIRs). The format is based on HDF5 and follows the netCDF-4 conventions.
See https://www.sofaconventions.org/ for specifications and documentation.
Index ¶
- Constants
- Variables
- type Attribute
- type File
- func (f *File) AmbisonicsOrder() (order int, ok bool)
- func (f *File) Close() error
- func (f *File) ConventionWarnings() []string
- func (f *File) DelayAt(m, r int) (float64, error)
- func (f *File) DelayDimensions() []string
- func (f *File) Duration() (float64, error)
- func (f *File) IRAt(m, r int) ([]float64, error)
- func (f *File) IRPeakdB(m, r int) (float64, error)
- func (f *File) IsBRIR() bool
- func (f *File) IsDirectivity() bool
- func (f *File) IsSHEncoded() bool
- func (f *File) IsSRIR() bool
- func (f *File) RangeMeasurements(fn func(m int, ir [][]float64) error) error
- func (f *File) RangeMeasurementsTF(fn func(m int, re, im [][]float64) error) error
- func (f *File) ReadMeasurement(m int) ([][]float64, error)
- func (f *File) ReadMeasurementSOS(m int) ([][]float64, error)
- func (f *File) ReadMeasurementTF(m int) (re, im [][]float64, err error)
- func (f *File) ReadMeasurementTFE(m int) (re, im [][][]float64, err error)
- func (f *File) SHCoefficientCount() int
- func (f *File) SHOrder() (lmax int, ok bool)
- func (f *File) SHWarnings() []string
- func (f *File) SamplingRateAt(m int) (float64, error)
- func (f *File) SamplingRateScalar() (float64, error)
- func (f *File) Save(path string, opts ...SaveOption) (err error)
- func (f *File) SourcePositionAt(m int) (Vector3, error)
- func (f *File) WriteTo(w io.Writer) (n int64, err error)
- type SaveOption
- type ValidationError
- type Variable
- type Vector3
Constants ¶
const ( DataTypeFIR = "FIR" // time-domain impulse responses DataTypeTF = "TF" // complex frequency-domain transfer functions DataTypeTFE = "TF-E" // TF with active emitter dimension ([M][R][E][N]); also carries SH-encoded HRTFs with E as SH coefficient index DataTypeSOS = "SOS" // second-order section (biquad) filter coefficients )
DataType values defined by the AES69 specification: the values of File.DataType this package reads and writes.
const ( // Coordinate systems a position dataset's Type attribute may name. CoordinateCartesian = "cartesian" CoordinateSpherical = "spherical" // CoordinateSphericalHarmonics marks EmitterPosition data of SH-encoded // files, where each emitter is one SH coefficient (see SHOrder). CoordinateSphericalHarmonics = "spherical harmonics" // UnitsSphericalDegrees is the conventional Units value for spherical // positions measured in degrees. UnitsSphericalDegrees = "degree, degree, metre" // UnitsCartesianMetres is the conventional Units value for cartesian // positions, as the SOFA convention tables give it. Files may also say // "metre, metre, metre"; Open reads the Units attribute as it is. UnitsCartesianMetres = "metre" )
SOFA file format constants.
const DefaultDeflateLevel = 4
DefaultDeflateLevel is the deflate level Save and WriteTo compress the audio data with unless WithDeflate sets another.
Variables ¶
var ErrIndexOutOfRange = errors.New("index out of range")
ErrIndexOutOfRange reports a measurement or receiver index outside the file's dimensions, or one for which no data is stored. Test for it with errors.Is.
var ErrNoSamplingRate = errors.New("no sampling rate stored")
ErrNoSamplingRate reports a file without Data.SamplingRate, as TF files have. Test for it with errors.Is.
var ErrNotLoaded = errors.New("audio data not loaded (file opened with OpenLazy)")
ErrNotLoaded reports an accessor such as IRAt that needs the whole audio array in memory, called on a File returned by OpenLazy. Read such a File with ReadMeasurement and its siblings, or open it with Open. Test for it with errors.Is.
var ErrNotSOFA = errors.New("not a SOFA file")
ErrNotSOFA reports that Open read an HDF5 file whose Conventions attribute is not "SOFA". Test for it with errors.Is.
var ErrTooLarge = errors.New("file declares too much data")
ErrTooLarge reports that Open read a file whose variables together declare more data than Open reads for a file of its size; see Open. Test for it with errors.Is.
var ErrUnsupportedDataType = errors.New("unsupported DataType")
ErrUnsupportedDataType reports a DataType this package cannot read or write: an empty or unknown value, GeneralFIR-E's "FIR-E" and the legacy "FIRE". Test for it with errors.Is.
var ErrVaryingSamplingRate = errors.New("sampling rate varies across measurements")
ErrVaryingSamplingRate reports that a file stores different sampling rates per measurement where a single rate was asked for. Test for it with errors.Is.
Functions ¶
This section is empty.
Types ¶
type Attribute ¶
Attribute is a netCDF attribute go-sofa does not map to a File field. Value is a string, a numeric scalar (int8 … uint64, float32, float64) or a non-empty slice of one numeric type. Open reads empty (null) attributes as "".
type File ¶
type File struct {
// Dimensions (M=measurements, R=receivers, E=emitters, N=samples)
M int // number of measurements
R int // number of receivers (e.g., 2 for binaural)
E int // number of emitters (typically 1; for SH-encoded HRTFs this is the SH coefficient index, with E = (Lmax+1)² — see (*File).SHOrder)
N int // number of samples per impulse response
// Spatial data. Save requires ReceiverPositions and SourcePositions and
// writes an empty ListenerPositions or EmitterPositions as the
// conventions' default, [0 0 0] cartesian in metres.
ListenerPositions []Vector3 // [M] listener positions for each measurement
ListenerUp Vector3 // listener's up vector
ListenerView Vector3 // listener's view direction
ReceiverPositions []Vector3 // [R] receiver positions (e.g., left/right ear)
SourcePositions []Vector3 // [M] source positions for each measurement
EmitterPositions []Vector3 // [E] emitter positions
// Measurement-dependent layouts, filled by Open only when a file stores
// them: ReceiverPosition [R,C,M] and EmitterPosition [E,C,M] as [M][R]
// and [M][E], ListenerView and ListenerUp [M,C] as [M]. The fields above
// then hold measurement 0. When set, Save writes these fields in the
// same layouts instead of the singular ones.
ReceiverPositionsM [][]Vector3
EmitterPositionsM [][]Vector3
ListenerViews []Vector3
ListenerUps []Vector3
// Coordinate system of each position dataset, from its Type and Units
// attributes. Type is "cartesian" or "spherical"; for spherical data the
// components are (azimuth, elevation, radius) and Units names their units,
// conventionally "degree, degree, metre". Both are stored trimmed but in
// the file's case (compare them with strings.EqualFold), and are empty
// when the file omits the attribute — absence is
// distinguishable from a value, because a reader that must know the
// coordinate system should say so rather than guess.
//
// Save requires a Type ("cartesian", "spherical" or "spherical
// harmonics") on every position it writes, and writes empty Units as the
// conventions' default for the Type: UnitsCartesianMetres for cartesian,
// UnitsSphericalDegrees otherwise. Units, here and on ListenerView, may
// name only metre and degree (also meter, metres, meters, degrees; any
// case), comma-separated.
ListenerPositionType string
ListenerPositionUnits string
ReceiverPositionType string
ReceiverPositionUnits string
SourcePositionType string
SourcePositionUnits string
EmitterPositionType string
EmitterPositionUnits string
// Coordinate system of ListenerView and ListenerUp, from ListenerView's
// Type and Units attributes. Save writes "cartesian" and "metre" when
// they are empty.
ListenerViewType string
ListenerViewUnits string
// Audio data — FIR (used when DataType == "FIR")
ImpulseResponses [][][]float64 // [M][R][N] the actual IR data
SamplingRate []float64 // [M] sampling rate in Hz (may be scalar)
Delay []float64 // delay in samples: 1 (shared), M, R or M×R (row-major [M][R]) values; see DelayAt
// Audio data — TF (used when DataType == "TF")
// Frequencies has length N. TFReal and TFImag have shape [M][R][N] and
// together encode the complex transfer function per measurement/receiver.
Frequencies []float64 // [N] frequency vector, Hz
TFReal [][][]float64 // [M][R][N] real part of complex TF
TFImag [][][]float64 // [M][R][N] imaginary part of complex TF
// Audio data — TF-E (used when DataType == "TF-E")
// Same Frequencies vector as TF, but with an active emitter dimension.
TFRealE [][][][]float64 // [M][R][E][N] real part of complex TF
TFImagE [][][][]float64 // [M][R][E][N] imaginary part of complex TF
// Audio data — SOS (used when DataType == "SOS")
// Second-order-section filter coefficients. Storage shape is [M][R][N]
// where N is 6 × (number of biquad sections); each biquad contributes
// six coefficients (b0, b1, b2, a0, a1, a2). SamplingRate and Delay
// (above) carry their FIR-style meaning.
SOSCoefficients [][][]float64 // [M][R][N]
// AES69 Metadata (global attributes)
Conventions string // "SOFA" for SOFA files
Version string // SOFA version (e.g., "1.0")
SOFAConventions string // specific convention (e.g., "SimpleFreeFieldHRIR", "SimpleFreeFieldHRSH" for SH-encoded HRTFs)
SOFAConventionsVersion string // convention version
DataType string // data type (e.g., "FIR")
RoomType string // room type if applicable
RoomVolume float64 // room volume in cubic metres; 0 when absent
RoomTemperature float64 // room temperature in kelvin; 0 when absent
Title string // descriptive title
DateCreated string // ISO 8601 date
DateModified string // ISO 8601 date
APIName string // API used to create the file
APIVersion string // API version
AuthorContact string // author contact information
Organization string // organization
License string // license information
ApplicationName string // application name
ApplicationVersion string // application version
Comment string // additional comments
History string // processing history
References string // references
Origin string // origin of the data
// Content go-sofa does not interpret, kept so that Open followed by
// Save loses nothing. Open fills these fields; callers may edit them,
// and Save writes them back.
//
// Attributes holds the global attributes that have no field above
// (DatabaseName, ListenerShortName, …). Variables holds the variables
// Save would not write otherwise (SourceView, RoomCornerA, char arrays
// such as ReceiverDescriptions, …). Open sorts both by name, since HDF5
// does not keep the order of attributes; Save writes them in slice
// order. VariableAttributes holds, per variable name, the attributes of
// the variables and dimensions Save does write beyond the ones it sets
// itself (Type/Units, Data.SamplingRate:Units, N:LongName/Units for TF).
// Dropped lists what Open could not keep (an unsupported data or
// attribute type), so that a lossy round trip is never silent.
Attributes []Attribute
Variables []Variable
VariableAttributes map[string][]Attribute
Dropped []string
// contains filtered or unexported fields
}
File holds the contents of a SOFA file: its AES69 attributes, positions and audio data. Open fills it completely, OpenLazy fills everything but the audio data (read it with ReadMeasurement and its siblings), and Save writes one built or modified in memory.
func Open ¶
Open reads a SOFA file. It checks that the file is a SOFA file, reads all data and metadata into the returned File and closes the file again before it returns, so the File holds no open handle. A failure to close the file is returned too, joined with any read error, and yields no File. Use OpenLazy to leave the audio data in the file and read it one measurement at a time, and OpenReader to read a file held in memory.
Before reading any data, Open refuses a file whose variables together declare more than 64 Mi elements or eight elements per byte of the file, whichever is more, or one variable declaring more than 2^30 elements, with an error wrapping ErrTooLarge: a file of a few kilobytes can declare gigabytes of never-written data. OpenLazy does not count the audio variables it leaves in the file.
func OpenLazy ¶
OpenLazy reads a SOFA file like Open, except for the audio variables (Data.IR, Data.Real and Data.Imag, Data.SOS): it checks their shapes but leaves their values in the file, so the returned File's ImpulseResponses, TFReal, TFImag, TFRealE, TFImagE and SOSCoefficients are nil. Dimensions, positions, attributes, SamplingRate, Delay, Frequencies and the extra variables are loaded as by Open.
Read the audio data one measurement at a time with ReadMeasurement, ReadMeasurementTF, ReadMeasurementTFE, ReadMeasurementSOS or the Range methods. Accessors that need the whole array in memory (IRAt, IRPeakdB) fail with ErrNotLoaded, and so does Save while the audio fields are empty.
The File keeps the file open until Close, which the caller must call; after it, reading audio data fails with fs.ErrClosed. Reads on one File are serialised, so it may be shared between goroutines.
How much memory OpenLazy saves depends on the file's storage layout. A chunked, compressed file is decompressed one chunk at a time, and typical HRTF files store one chunk per receiver across all measurements (CIPIC: Data.IR [1250,2,200] in chunks of [1250,1,200]). There the first ReadMeasurement decompresses every receiver's chunk and keeps it cached, so OpenLazy saves memory over Open only for files chunked along M or stored contiguously. When chunks span several measurements, the cache holds the chunks one measurement spans (up to 256 MiB per audio variable), so reading every measurement decompresses each chunk once.
func OpenLazyReader ¶
OpenLazyReader is OpenLazy for a SOFA file of size bytes read from r, such as a bytes.Reader or an *os.File opened elsewhere. The File reads audio data from r until Close, so r must stay usable until then; Close does not close r.
func OpenReader ¶
OpenReader reads a SOFA file of size bytes from r, such as a bytes.Reader over a file held in memory or an embedded asset, like Open reads one from disk: it reads all data and metadata into the returned File, and r is not used after OpenReader returns. Reads stay within the first size bytes of r. OpenReader never closes r.
func (*File) AmbisonicsOrder ¶
AmbisonicsOrder returns the Ambisonics order of an SRIR file, detected from its receiver count R = (order+1)². ok is false for files that are not SRIR, and for SRIR files whose R is not such a square, which usually means the receivers are the raw capsules of a microphone array.
func (*File) Close ¶
Close releases the file handle of a File returned by OpenLazy; after it, the File's metadata stays usable but reading audio data fails with fs.ErrClosed. Closing again does nothing and returns nil. For any other File, Close does nothing and returns nil: Open already closes the file it reads, and the File holds all data in memory.
func (*File) ConventionWarnings ¶
ConventionWarnings returns advisory messages about the file's conformance: SOFA 2.x features (the FreeFieldHRTF convention, DataType TF-E, spherical-harmonics positions) in a file whose Version is below 2.0, a SOFAConventionsVersion its registered convention does not know (custom conventions are not checked), a SimpleFreeField* file with other than two receivers (libmysofa rejects it), a free-field HRTF file whose RoomType is not free field (sofar rejects it), and the checks of the convention's own rules, such as missing optional room metadata. Unlike validation errors they never stop Save; callers should surface them to users.
func (*File) DelayAt ¶
DelayAt returns the delay in samples of measurement m, receiver r, broadcasting Data.Delay stored as [I], [I,R], [R], [M] or [M,R]. A file without Data.Delay has no delay, so DelayAt returns 0. It fails with ErrIndexOutOfRange when m or r is outside [0,M)×[0,R) or the stored delay does not fit its layout.
func (*File) DelayDimensions ¶
DelayDimensions returns the netCDF dimension names of Delay, such as ["I", "R"] or ["M"]: the ones Open read from the file, which tell [M] from [R] when M == R, or, for a File built in memory or a Delay changed since, the layout its length implies ([I], [M,R], [M] or [R], checked in that order). It returns nil for an empty Delay.
func (*File) Duration ¶
Duration returns the length of the impulse responses in seconds, N divided by the (first) sampling rate. It fails with ErrUnsupportedDataType for non-FIR files, where N counts frequency bins or filter coefficients, and when no positive sampling rate is stored.
func (*File) IRAt ¶
IRAt returns the impulse response for measurement m, receiver r. It fails with ErrUnsupportedDataType for non-FIR files and with ErrIndexOutOfRange when m or r is outside [0,M)×[0,R) or no complete response (N samples) is stored there. On a File returned by OpenLazy, whose responses stay in the file, it fails with ErrNotLoaded (use ReadMeasurement there) unless the caller has filled ImpulseResponses.
func (*File) IRPeakdB ¶
IRPeakdB returns the peak level in dB (relative to 1.0) for measurement m, receiver r; a silent response yields -Inf. Errors are those of IRAt.
func (*File) IsBRIR ¶
IsBRIR reports whether the file holds binaural room impulse responses, that is, whether SOFAConventions is SingleRoomDRIR. Save requires such files to hold FIR data and to carry a non-zero ListenerView and ListenerUp; an empty RoomType is written as reverberant. MultiSpeakerBRIR files use DataType FIRE, which is not supported.
func (*File) IsDirectivity ¶
IsDirectivity reports whether the file holds source directivities, that is, whether SOFAConventions names a Directivity convention such as FreeFieldDirectivityTF.
In these files the measurement dimension M indexes the orientation of the source being characterised, not a source position around a listener as in HRTF sets. Save only checks that FreeFieldDirectivityTF files hold TF data, and writes the conventions' default SourceView and SourceUp when Variables lacks them and an empty Reference attribute on SourcePosition, SourceView and SourceUp when none is set; further rules wait for an example file to check them against.
func (*File) IsSHEncoded ¶
IsSHEncoded reports whether this file represents spherical-harmonic (SH) encoded HRTF/transfer-function data. SH SOFA files reuse the TF-E DataType and store one SH coefficient per emitter (E = (Lmax+1)²); AES69 marks them with EmitterPosition:Type = "spherical harmonics". See SHOrder for the detection rule.
func (*File) IsSRIR ¶
IsSRIR reports whether the file holds spatial room impulse responses, that is, whether SOFAConventions is SingleRoomSRIR. SingleRoomMIMOSRIR files use DataType FIR-E, which is not supported.
func (*File) RangeMeasurements ¶
RangeMeasurements calls fn with the impulse responses ([R][N], as from ReadMeasurement) of each measurement in order. It stops at the first error, from reading or from fn, and returns it; an error of fn is returned unwrapped. For a File returned by OpenLazy only one measurement is held in memory at a time, unless fn keeps it, and the stored shape is checked before fn is first called, so a File whose M was changed fails with ErrIndexOutOfRange even when M is now 0 or less.
func (*File) RangeMeasurementsTF ¶
RangeMeasurementsTF calls fn with the real and imaginary parts ([R][N], as from ReadMeasurementTF) of each measurement of a TF file in order. It stops like RangeMeasurements.
func (*File) ReadMeasurement ¶
ReadMeasurement returns the impulse responses of measurement m, shaped [R][N]. For a File returned by OpenLazy it reads just that measurement from the file into new slices; otherwise it returns ImpulseResponses[m], which shares memory with the File. It fails with ErrUnsupportedDataType for non-FIR files, with ErrIndexOutOfRange when m is outside [0,M) or no data is stored there, and with fs.ErrClosed after Close of a lazy File. A lazy File reads the audio variable OpenLazy found for its DataType; after DataType, M, R, N or E are changed, reads fail with ErrUnsupportedDataType when the file holds no variable for the new DataType and with ErrIndexOutOfRange when its shape no longer matches, or with fs.ErrClosed once the File is closed.
func (*File) ReadMeasurementSOS ¶
ReadMeasurementSOS returns the second-order-section coefficients of measurement m of an SOS file, shaped [R][N] like SOSCoefficients[m]. It reads and fails like ReadMeasurement, with ErrUnsupportedDataType for files other than SOS.
func (*File) ReadMeasurementTF ¶
ReadMeasurementTF returns the real and imaginary parts of the transfer functions of measurement m of a TF file, each shaped [R][N]. It reads and fails like ReadMeasurement, with ErrUnsupportedDataType for files other than TF.
func (*File) ReadMeasurementTFE ¶
ReadMeasurementTFE returns the real and imaginary parts of the transfer functions of measurement m of a TF-E file, each shaped [R][E][N] like TFRealE[m]. It reads and fails like ReadMeasurement, with ErrUnsupportedDataType for files other than TF-E.
func (*File) SHCoefficientCount ¶
SHCoefficientCount returns the number of SH coefficients stored per (measurement, receiver, frequency) tuple. Returns 0 when the file is not SH-encoded; otherwise returns E = (Lmax+1)².
func (*File) SHOrder ¶
SHOrder returns the spherical-harmonic order Lmax encoded in this file. ok is false if the file is not SH-encoded. Detection rule: DataType is TF-E, the file declares SH (EmitterPosition:Type is "spherical harmonics", or — only when that Type is empty — the convention name or History says so), and E equals (L+1)² for some integer L ≥ 0, so E = 1 is order 0.
func (*File) SHWarnings ¶
SHWarnings returns advisory messages about possibly-malformed or possibly-undocumented spherical-harmonic encoding. Empty when the file is unambiguous (either clearly SH or clearly not). Callers should surface these to users without treating them as errors.
func (*File) SamplingRateAt ¶
SamplingRateAt returns the sampling rate in Hz of measurement m, broadcasting an [I] rate to every measurement. It fails with ErrIndexOutOfRange when m is outside [0,M) and with ErrNoSamplingRate when none is stored.
func (*File) SamplingRateScalar ¶
SamplingRateScalar returns the file's single sampling rate in Hz: the [I] value, or the [M] values when they are all equal. It fails with ErrNoSamplingRate when none is stored and with ErrVaryingSamplingRate when the per-measurement rates differ; use SamplingRateAt then.
func (*File) Save ¶
func (f *File) Save(path string, opts ...SaveOption) (err error)
Save writes the SOFA file to the specified path. It validates the File struct before writing and creates a fully compliant SOFA file with netCDF-4/HDF5 dimension scales.
Save is atomic: the file is written to a temporary file in the same directory, flushed and fsynced, and then renamed over path. A failed Save leaves any existing file at path untouched and removes the temporary file. If path already exists its permission bits are kept; otherwise the new file gets mode 0644.
Like the SOFA Toolbox's SOFAsave, Save records its own provenance in the written file, without changing the File: APIName "go-sofa" and go-sofa's module version as APIVersion, the save time as DateModified, and as DateCreated when that is empty. When the File names another API (or another go-sofa version), History gains the line "resaved by go-sofa <version> from <APIName> <APIVersion>". Set ApplicationName and ApplicationVersion to record your program.
The save time is the current time, or the SOURCE_DATE_EPOCH environment variable (seconds since the Unix epoch) when set; a malformed value, the empty string included, is an error. Output is otherwise deterministic: with SOURCE_DATE_EPOCH set, saving the same File twice produces byte-identical files.
All required SOFA attributes and datasets are written, along with optional fields if present in the File struct. ReceiverPositions and SourcePositions are required; an empty ListenerPositions or EmitterPositions is written as the conventions' default, [0 0 0] cartesian in metres, again without changing the File. So are global attributes the file's SOFAConventions makes mandatory beyond the generic ones (DatabaseName and ListenerShortName for SimpleFreeFieldHRIR, …): Save writes the empty default the SOFA convention tables give them when Attributes lacks one. Likewise, the SourceView and SourceUp variables that SingleRoomSRIR, SingleRoomDRIR and FreeFieldDirectivityTF make mandatory are written with the tables' defaults (and the attributes VariableAttributes holds for them) when Variables lacks them, and the Reference attribute FreeFieldDirectivityTF makes mandatory on SourcePosition, SourceView and SourceUp as "" where none is set. An empty RoomType is written as the convention's default: reverberant for SingleRoomDRIR, shoebox for SingleRoomSRIR when Variables holds RoomCornerA and RoomCornerB, free field otherwise.
The audio data is deflated at level DefaultDeflateLevel; WithDeflate sets another level, WithDeflate(0) writes it uncompressed.
Returns an error if:
- Validation fails (missing required fields, invalid dimensions, etc.)
- An option is invalid (a deflate level outside 0–9)
- HDF5 file creation fails
- Any write, flush, close, sync or rename operation fails
- f came from OpenLazy and its audio fields are still empty (ErrNotLoaded)
func (*File) SourcePositionAt ¶
SourcePositionAt returns the source position of measurement m, broadcasting an [I,C] position to every measurement. It fails with ErrIndexOutOfRange when m is outside [0,M) or no position is stored.
func (*File) WriteTo ¶
WriteTo writes the SOFA file to w, as Save writes it to a file without options (audio data deflated at DefaultDeflateLevel): it validates f first and produces the same bytes. It returns the number of bytes written, and implements io.WriterTo.
The file is assembled in memory (HDF5 needs random access while writing) and handed to w in one Write only once it is complete, so a validation or encoding error writes nothing to w. An error from w is returned together with the bytes w accepted.
type SaveOption ¶ added in v0.3.0
type SaveOption func(*saveOptions)
SaveOption configures how Save writes a file.
func WithDeflate ¶ added in v0.3.0
func WithDeflate(level int) SaveOption
WithDeflate stores the audio data (Data.IR, Data.Real and Data.Imag, or Data.SOS) deflated at level 1 (fastest) to 9 (smallest) instead of DefaultDeflateLevel; 0 stores it uncompressed and contiguous.
Deflated data is byte-shuffled and split into chunks of one receiver across all measurements, the layout of most SOFA files written by netCDF-C. Chunks hold fewer measurements when that exceeds 4 MiB, but there are never more than 64 chunks (one B-tree node, all libmysofa reads): large files store several receivers per chunk, and only very large ones more measurements.
Level 4 shrinks typical HRIR sets to about the size of their netCDF-C originals (MIT KEMAR: 5.9 MB uncompressed, 1.1 MB deflated, 1.2 MB original); higher levels save little more and take much longer.
type ValidationError ¶
ValidationError reports a File that Save refuses to write. Field names the File field at fault, such as "M", "ImpulseResponses", "SourcePositionType" or "Variables"; Err says what is wrong with it. Save returns every validation failure as a *ValidationError, which callers can extract with errors.As. The message starts with Field, as in "M: must be > 0, got 0" or "ImpulseResponses[0] length 1 does not match R=2".
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap returns Err, so that errors.Is sees sentinels such as ErrUnsupportedDataType through a ValidationError.
type Variable ¶
type Variable struct {
Name string
Dims []string
Shape []int
Values []float64
Chars []byte
Attributes []Attribute
}
Variable is a netCDF variable go-sofa does not interpret, such as SourceView, RoomCornerA or a char array like ReceiverDescriptions.
Shape gives the size of each axis and Dims their netCDF dimension names (nil when the file does not name them; Save then writes the variable without dimensions, which netCDF reads as phony ones). Exactly one of Values and Chars holds the data, row-major: Values for numeric variables, which Open reads and Save writes as float64, and Chars for char arrays, one byte per element (0 for an unset character).
type Vector3 ¶
type Vector3 struct {
X, Y, Z float64
}
Vector3 is one coordinate triplet of a position or orientation variable. Its units are those the variable's Type and Units attributes name: X, Y, Z in metres for "cartesian"; azimuth, elevation (degrees, or radians where a file's Units say so; Save accepts only degrees) and radius in metres for "spherical" and "spherical harmonics" (where each EmitterPosition row is one SH coefficient's emitter).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
sofa2json
command
Command sofa2json exports SOFA files to JSON.
|
Command sofa2json exports SOFA files to JSON. |
|
sofainfo
command
Command sofainfo prints a metadata summary of SOFA files: AES69 global attributes, dimensions and basic audio parameters.
|
Command sofainfo prints a metadata summary of SOFA files: AES69 global attributes, dimensions and basic audio parameters. |
|
sofaprobe
command
Command sofaprobe inspects SOFA files and dumps their HDF5 structure, attributes, datasets and dimension scales, followed by a preview of the audio data (Data.IR, Data.Real, Data.Imag or Data.SOS).
|
Command sofaprobe inspects SOFA files and dumps their HDF5 structure, attributes, datasets and dimension scales, followed by a preview of the audio data (Data.IR, Data.Real, Data.Imag or Data.SOS). |
|
internal
|
|
|
clitest
Package clitest builds small, valid SOFA files for the command tests in cmd/.
|
Package clitest builds small, valid SOFA files for the command tests in cmd/. |
|
interop/gen
command
Command gen writes one SOFA file per supported DataType (FIR, TF, TF-E, SOS) with sofa.Save, filled with known values, plus an expected.json sidecar describing what a reference reader must see.
|
Command gen writes one SOFA file per supported DataType (FIR, TF, TF-E, SOS) with sofa.Save, filled with known values, plus an expected.json sidecar describing what a reference reader must see. |
|
interop/mysofa
command
Command mysofa checks that libmysofa, the reader most SOFA renderers use, loads the files go-sofa writes.
|
Command mysofa checks that libmysofa, the reader most SOFA renderers use, loads the files go-sofa writes. |
|
interop/toolbox
command
Command toolbox is the Go side of the SOFA Toolbox cross-validation (scripts/matlab/roundtrip.m, README "Cross-validation").
|
Command toolbox is the Go side of the SOFA Toolbox cross-validation (scripts/matlab/roundtrip.m, README "Cross-validation"). |