room

package
v0.0.0-...-e1b70a5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Pastel Colors
	PastelRed      = "#FF6961"
	PastelOrange   = "#FFD1A1"
	PastelYellow   = "#FDFD96"
	PastelGreen    = "#77DD77"
	PastelBlue     = "#AEC6CF"
	PastelPurple   = "#CBAACB"
	PastelPink     = "#FFB7CE"
	PastelTeal     = "#99C5B3"
	PastelLavender = "#B39EB5"
	PastelPeach    = "#FFDAC1"
	PastelMint     = "#B5EAD7"
	PastelSky      = "#C1E1C1"

	// Bright Colors
	BrightRed      = "#FF4D4D"
	BrightOrange   = "#FFA64D"
	BrightYellow   = "#FFFF4D"
	BrightGreen    = "#4DFF4D"
	BrightBlue     = "#4D9EFF"
	BrightPurple   = "#B64DB6"
	BrightPink     = "#FF4D93"
	BrightTeal     = "#4DDBC4"
	BrightLavender = "#C44DFF"
	BrightPeach    = "#FFB84D"
	BrightMint     = "#4DFFD1"
	BrightSky      = "#4DC4FF"
)
View Source
const (
	SABINE          = 0.161
	EYERING         = 55.3
	SCHROEDER_COEFF = 2000
)
View Source
const INF = 1e9
View Source
const LISTEN_DIST_INTO_TRIANGLE = 0.32

Value from Thomas Northward posted on GearSpae

View Source
const MS float64 = 1.0 / 1000.0
View Source
const SCALE = 1000
View Source
const SPEED_OF_SOUND = 343.0

Variables

View Source
var NoHit = Arrival{Gain: 0.0, Distance: INF}

Functions

func AnglePitch

func AnglePitch(normal, direction, tangent pt.Vector) float64

Helper: Calculate pitch from speaker normal to direction

func AngleYaw

func AngleYaw(normal, direction, tangent, bitangent pt.Vector) float64

Helper: Calculate yaw from speaker normal to direction

func ComputeMeshVolume

func ComputeMeshVolume(mesh *pt.Mesh) float64

ComputeMeshVolume calculates the volume of a closed mesh Note: The mesh must be closed and properly oriented (consistent winding order) Returns: Volume in cubic units of the mesh coordinates

func EnergyOverWindow

func EnergyOverWindow(arrivals []Arrival, windowMS float64, floor float64) (float64, error)

func NewDirectivity

func NewDirectivity(horiz, vert map[float64]float64) *directivity

Returns a directivity struct, which can compute the gain of a ray shot from a given direction

horiz and vert are maps of angle in degrees to gain in dB. Gain should always be negative except at 0 degrees. Angles must be positive and in ascending order. The gain at angle θ is equal to the gain at angle -θ.

func V

func V(X, Y, Z float64) pt.Vector

V is a shorthand constructor for pt.Vector

Types

type AcousticPathJSON

type AcousticPathJSON struct {
	Reflections         []ReflectionJSON    `json:"reflections"`
	Shot                ShotJSON            `json:"shot"`
	GainFromReflections float64             `json:"gainFromReflections"` // stored in dB
	GainFromDistance    float64             `json:"gainFromDistance"`    // stored in dB
	Gain                float64             `json:"gain"`                // stored in dB
	Distance            float64             `json:"distance"`
	NearestApproach     NearestApproachJSON `json:"nearestApproach"`
	Name                string              `json:"name,omitempty"`
	Color               string              `json:"color,omitempty"`
	Thickness           float64             `json:"thickness,omitempty"`
}

func ArrivalToAcousticPathJSON

func ArrivalToAcousticPathJSON(a Arrival) AcousticPathJSON

type AnalysisResults

type AnalysisResults struct {
	ITD              float64 `json:"ITD,omitempty"`
	EnergyOverWindow float64 `json:"avg_energy_over_window,omitempty"`
	ITD2             float64 `json:"ITD_2,omitempty"`
	AvgGain5ms       float64 `json:"avg_gain_5ms,omitempty"`
	ListenPosX       float64 `json:"listen_pos_x,omitempty"`
	T60Sabine        float64 `json:"T60_sabine,omitempty"`
	T60Eyering       float64 `json:"T60_eyering,omitempty"`
	SchroederFreq    float64 `json:"schroeder_freq,omitempty"`
	Volume           float64 `json:"volume,omitempty"`
	NominalT60       float64 `json:"nominal_T60,omitempty"`
}

type Annotations

type Annotations struct {
	Points     []Point
	Paths      []PsalmPath
	Arrivals   []Arrival
	Zones      []Zone
	PathColors map[int]string // This is ugly but yolo
}

func NewAnnotations

func NewAnnotations() *Annotations

func (Annotations) WriteToJSON

func (a Annotations) WriteToJSON(filename string) error

SaveAnnotationsToJson saves points, paths, and both types of paths to a JSON file

type Arrival

type Arrival struct {
	// The shot that created this arrival
	Shot Shot
	// Position of the last reflection
	LastReflection pt.Vector
	// Slice of positions of all reflections
	AllReflections []Reflection
	// Gain contribution from imperfect reflection, dB
	GainFromReflections float64
	// Gain contribution from distance (6dB rule)
	GainFromDistance float64
	// Gain in dB relative to the direct signal
	Gain float64
	// Total distance traveled by this ray across all reflections, in meters
	Distance float64
	// The nearest this arrival came to the listening position
	NearestApproachDistance float64
	// The position of the nearest aproach
	NearestApproachPosition pt.Vector
}

Arrival defines a reflection that arrives within the RFZ

func (Arrival) DirectDist

func (a Arrival) DirectDist() float64

Returns the distance traveled by the direct signal from source to position of last reflection

func (Arrival) ITD

func (a Arrival) ITD() float64

Returns time delay between direct signal and reflection, in milliseconds

func (Arrival) NullFreq

func (a Arrival) NullFreq() float64

type Bounds

type Bounds struct {
	Min, Max float64
}

type ListeningTriangle

type ListeningTriangle struct {
	// A point on the front wall
	ReferencePosition pt.Vector
	// The normal vector of the front wall
	//
	// TODO: this is currently ignored. Implement this properly.
	ReferenceNormal pt.Vector
	// Distance of the sources from the front wall
	DistFromFront float64
	// Distance of the sources from the horizontal center of the triangle
	DistFromCenter float64
	// Height of the sources
	SourceHeight float64
	// Height of the listen position
	ListenHeight float64
}

func (ListeningTriangle) Deviation

func (t ListeningTriangle) Deviation(listenPos pt.Vector) float64

func (ListeningTriangle) LeftSourceNormal

func (t ListeningTriangle) LeftSourceNormal() pt.Vector

func (ListeningTriangle) LeftSourcePosition

func (t ListeningTriangle) LeftSourcePosition() pt.Vector

func (ListeningTriangle) ListenDistance

func (t ListeningTriangle) ListenDistance() float64

func (ListeningTriangle) ListenPosition

func (t ListeningTriangle) ListenPosition() (ListenPos, EquilateralPos pt.Vector)

ListenPosition returns two points: the ideal Listening Position within the room and the position of a hypothetical equilateral triangle with the two sources.

The Listening Position is a constant distance into the triangle (TOWARDS the line connecting the two sources), to place the listener's ears directly on the paths from source to the third point of the equilateral triangle ("EquilateralPos").

func (ListeningTriangle) RightSourceNormal

func (t ListeningTriangle) RightSourceNormal() pt.Vector

func (ListeningTriangle) RightSourcePosition

func (t ListeningTriangle) RightSourcePosition() pt.Vector

type LoudSpeakerSpec

type LoudSpeakerSpec struct {
	Xdim, Ydim, Zdim float64
	Yoff, Zoff       float64
	HDirectivityMap  map[float64]float64
	VDirectivityMap  map[float64]float64
	// contains filtered or unexported fields
}

func (LoudSpeakerSpec) GainDB

func (spec LoudSpeakerSpec) GainDB(yaw, pitch float64) float64

type Material

type Material struct {
	// contains filtered or unexported fields
}

func NewMaterial

func NewMaterial(alphaMap map[float64]float64) Material

func PerfectAbsorber

func PerfectAbsorber() Material

func PerfectReflector

func PerfectReflector() Material

func (Material) Alpha

func (m Material) Alpha(freq float64) float64

type MaterialJSON

type MaterialJSON struct {
	Absorption map[float64]float64 `json:"absorption"`
}

func MaterialToJSON

func MaterialToJSON(m Material) MaterialJSON

func (*MaterialJSON) MarshalJSON

func (m *MaterialJSON) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshaling

type NearestApproachJSON

type NearestApproachJSON struct {
	Position PointJSON `json:"position"`
	Distance float64   `json:"distance"`
}

type Path

type Path []pt.Vector

type Path2D

type Path2D []Point2D

func (Path2D) BoundingBox

func (p Path2D) BoundingBox() (XMin, XMax, YMin, YMax float64)

func (Path2D) Scale

func (p Path2D) Scale(v View) Path2D

func (Path2D) Translate

func (p Path2D) Translate(x, y float64) Path2D

type PathJSON

type PathJSON struct {
	Points    []PointJSON `json:"points"`
	Name      string      `json:"name,omitempty"`
	Color     string      `json:"color,omitempty"`
	Thickness float64     `json:"thickness,omitempty"`
}

func PathToJSON

func PathToJSON(path PsalmPath) PathJSON

type Plane

type Plane struct {
	Point  pt.Vector
	Normal pt.Vector
	U, V   pt.Vector
}

func MakePlane

func MakePlane(point, normal pt.Vector) Plane

func (Plane) IntersectTriangle

func (p Plane) IntersectTriangle(t pt.TriangleInt) (pt.Vector, pt.Vector, bool)

func (Plane) MeshToPath

func (p Plane) MeshToPath(m *pt.Mesh) []Path2D

func (Plane) Project

func (p Plane) Project(point pt.Vector) pt.Vector

func (Plane) SliceMesh

func (p Plane) SliceMesh(m *pt.Mesh) []Path

type Point

type Point struct {
	Position pt.Vector
	Name     string
	Color    string
}

Point represents a point in 3D space with size and name

type Point2D

type Point2D struct {
	X, Y float64
}

func To2D

func To2D(v pt.Vector) Point2D

To2D converts a 3D vector to a 2D point

func (Point2D) Scale

func (p Point2D) Scale(s float64) Point2D

func (Point2D) Translate

func (p Point2D) Translate(x, y float64) Point2D

type PointJSON

type PointJSON struct {
	X     float64 `json:"x"`
	Y     float64 `json:"y"`
	Z     float64 `json:"z"`
	Name  string  `json:"name,omitempty"`
	Color string  `json:"color,omitempty"`
}

func PointToJSON

func PointToJSON(p Point) PointJSON

type PsalmPath

type PsalmPath struct {
	Points    []Point
	Name      string
	Color     string
	Thickness float64
}

Path represents a sequence of points with optional styling metadata

type RayJSON

type RayJSON struct {
	Origin    PointJSON  `json:"origin"`
	Direction VectorJSON `json:"direction"`
}

type Reflection

type Reflection struct {
	// Position of the reflection
	Position pt.Vector
	// Normal of the surface at the reflection
	Normal pt.Vector
	// Acoustic properties of the surface we reflected off of
	Surface Surface
}

type ReflectionJSON

type ReflectionJSON struct {
	Position PointJSON   `json:"position"`
	Normal   VectorJSON  `json:"normal,omitempty"`
	Surface  SurfaceJSON `json:"surface,omitempty"`
}

func ReflectionToJSON

func ReflectionToJSON(r Reflection) ReflectionJSON

type Room

type Room struct {
	M *pt.Mesh
}

func NewEmptyRoom

func NewEmptyRoom() Room

func NewFrom3MF

func NewFrom3MF(filepath string, materials map[string]Material) (*Room, map[string]*Surface, error)

func (*Room) AddPrism

func (r *Room) AddPrism(XBound, YBound, ZBound Bounds, name string, material Material) error

func (*Room) AddSurface

func (r *Room) AddSurface(surface *Surface) error

func (*Room) AddWall

func (r *Room) AddWall(point pt.Vector, normal pt.Vector, name string, material Material) error

func (*Room) GetSpeakerCone

func (r *Room) GetSpeakerCone(speaker Speaker, angle float64, N int, color string) ([]PsalmPath, error)

func (*Room) InteriorMesh

func (r *Room) InteriorMesh() (*pt.Mesh, error)

InteriorMesh returns the mesh describing the innermost set of walls in the room

func (*Room) NominalT60

func (r *Room) NominalT60() (float64, error)

func (*Room) SchroederFreq

func (r *Room) SchroederFreq() (float64, error)

SchroederFreq returns the Schroeder frequency of the room, which is the frequency at which the reverb transitions from modal to specular behavior

func (*Room) SurfaceArea

func (r *Room) SurfaceArea() (float64, error)

SurfaceArea returns the surface area of the INTERIOR of the room

func (*Room) T60Eyring

func (r *Room) T60Eyring(freq float64) (float64, error)

func (*Room) T60Sabine

func (r *Room) T60Sabine(freq float64) (float64, error)

T60Sabine returns the Sabine reverberation time of the room in seconds

func (*Room) TraceShot

func (r *Room) TraceShot(shot Shot, listenPos pt.Vector, params TraceParams) ([]Arrival, error)

TraceShot traces the path taken by a shot until it either arrives at the RFZ or satisfies the othe criteria in params.

See the Params struct type.

func (*Room) TraceShotUnconditional

func (r *Room) TraceShotUnconditional(shot Shot, listenPos pt.Vector, params TraceParams) ([]Arrival, error)

TraceShot traces the path taken by a shot until it either arrives at the RFZ or satisfies the othe criteria in params.

See the Params struct type.

func (*Room) Volume

func (r *Room) Volume() (float64, error)

Volume returns the volume of the INTERIOR of the room

type Scene

type Scene struct {
	Sources           []Speaker
	ListeningPosition pt.Vector
	ListeningTriangle ListeningTriangle
	Room              *Room
}

func (Scene) BoundingBox

func (scene Scene) BoundingBox(p Plane) (XMin, XMax, YMin, YMax float64)

func (Scene) PlotITD

func (scene Scene) PlotITD(X, Y int, arrivals []Arrival, window int) (image.Image, error)

type Shot

type Shot struct {
	Ray        pt.Ray
	Normal     pt.Ray
	Gain       float64
	Yaw, Pitch float64
	SourceName string
}

func (Shot) Equal

func (s Shot) Equal(test Shot) bool

type ShotJSON

type ShotJSON struct {
	Ray          RayJSON `json:"ray"`
	SourceNormal RayJSON `json:"sourceNormal"`
	Gain         float64 `json:"gain"`  // stored in dB
	Yaw          float64 `json:"yaw"`   // stored in deg
	Pitch        float64 `json:"pitch"` // stored in deg
	SourceName   string  `json:"sourceName"`
}

type Size

type Size struct {
	X int
	Y int
}

type Source

type Source struct {
	Position        pt.Vector
	NormalDirection pt.Vector
	Name            string
}

type Speaker

type Speaker struct {
	LoudSpeakerSpec
	Source
}

func NewSpeaker

func NewSpeaker(spec LoudSpeakerSpec, pos pt.Vector, dir pt.Vector, name string) Speaker

func (Speaker) IsInsideRoom

func (s Speaker) IsInsideRoom(m *pt.Mesh, listenPos pt.Vector) (offendingVertex pt.Vector, intersectingPoint pt.Vector, ok bool)

IsInsideRoom returns true if the speaker is inside the innermost set of walls of the mesh

func (*Speaker) Sample

func (s *Speaker) Sample(numSamples int, horizRange, vertRange float64) []Shot

func (*Speaker) SampleCone

func (s *Speaker) SampleCone(angleDegrees float64, numRays int) []pt.Ray

func (*Speaker) SampleWithNormal

func (s *Speaker) SampleWithNormal(targetVector pt.Vector, numSamples int, horizRange, vertRange float64) []Shot

type Status

type Status string
const (
	Success       Status = "success"
	ErrValidation Status = "validation_error"
	ErrSimulation Status = "simulation_error"
)

type Summary

type Summary struct {
	Status  Status          `json:"status"`
	Errors  []string        `json:"errors,omitempty"`
	Results AnalysisResults `json:"results"`
}

Summary Results Schema

func NewSummary

func NewSummary() *Summary

func (*Summary) AddError

func (r *Summary) AddError(status Status, err error)

func (*Summary) Successful

func (r *Summary) Successful()

func (Summary) WriteToJSON

func (r Summary) WriteToJSON(filename string) error

type Surface

type Surface struct {
	Name     string
	Material Material
	M        *pt.Mesh
}

func (*Surface) Absorber

func (s *Surface) Absorber(thickness, height float64, material Material) *Surface

func (*Surface) Normal

func (s *Surface) Normal() pt.Vector

type SurfaceJSON

type SurfaceJSON struct {
	Material MaterialJSON `json:"material"`
	Name     string       `json:"name,omitempty"`
}

func SurfaceToJSON

func SurfaceToJSON(s Surface) SurfaceJSON

type TraceParams

type TraceParams struct {
	// Maximum number of reflections to simulate
	Order int
	// Stop tracing after the reflection loses this many dB relative to the direct signal
	GainThreshold float64
	// Stop tracing after this many seconds
	TimeThreshold float64
	// Only reflections that pass within this distance from the listening position will be counted as hits
	//
	// Distance in meters
	RFZRadius float64
}

TraceParams contains parameters to guide tracing

type Triangle

type Triangle struct {
	pt.Triangle
	Surface *Surface
}

func (*Triangle) Intersect

func (t *Triangle) Intersect(r pt.Ray) pt.Hit

func (Triangle) T

func (t Triangle) T() *pt.Triangle

type VectorJSON

type VectorJSON struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
	Z float64 `json:"z"`
}

JSON schema types

func VectorToJSON

func VectorToJSON(v pt.Vector) VectorJSON

Conversion functions

type View

type View struct {
	Scene Scene
	XSize int
	YSize int
	Plane Plane
	// contains filtered or unexported fields
}

func (*View) PlotArrivals3D

func (view *View) PlotArrivals3D(arrivals []Arrival) (image.Image, error)

type Wall

type Wall struct {
	Name     string
	Material Material
}

type Zone

type Zone struct {
	Center pt.Vector
	Radius float64
}

type ZoneJSON

type ZoneJSON struct {
	X            float64 `json:"x"`
	Y            float64 `json:"y"`
	Z            float64 `json:"z"`
	Radius       float64 `json:"radius"`
	Name         string  `json:"name,omitempty"`
	Color        string  `json:"color,omitempty"`
	Transparency float64 `json:"transparency,omitempty"`
}

func ZoneToJSON

func ZoneToJSON(z Zone) ZoneJSON

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL