$ErrorActionPreference = 'Stop' $projectRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..')) $utf8WithoutBom = [System.Text.UTF8Encoding]::new($false) function New-CoordinateSystem { return [ordered]@{ handedness = 'right' xAxis = 'right' yAxis = 'up' zAxis = 'toward-scene' } } function New-RectangularArray { param( [Parameter(Mandatory = $true)][string]$Id, [Parameter(Mandatory = $true)][string]$Name, [Parameter(Mandatory = $true)][string]$Description, [Parameter(Mandatory = $true)][int]$Columns, [Parameter(Mandatory = $true)][int]$Rows, [Parameter(Mandatory = $true)][double]$Width, [Parameter(Mandatory = $true)][double]$Height ) $microphones = [System.Collections.Generic.List[object]]::new() for ($row = 0; $row -lt $Rows; $row++) { for ($column = 0; $column -lt $Columns; $column++) { $index = $row * $Columns + $column $x = if ($Columns -eq 1) { 0 } else { -$Width / 2 + $column * $Width / ($Columns - 1) } $y = if ($Rows -eq 1) { 0 } else { -$Height / 2 + $row * $Height / ($Rows - 1) } $microphones.Add([ordered]@{ id = 'mic-{0:D3}' -f ($index + 1) position = @([Math]::Round($x, 6), [Math]::Round($y, 6), 0) }) } } return [ordered]@{ schemaVersion = '1.0.0' kind = 'micarrsim.array' id = $Id name = $Name description = $Description units = 'm' coordinateSystem = New-CoordinateSystem aperture = [ordered]@{ width = $Width; height = $Height } microphones = $microphones } } function Write-ArrayFixture { param([Parameter(Mandatory = $true)]$Definition) $outputPath = Join-Path $projectRoot "assets/array-geometries/$($Definition.id).array.json" $json = $Definition | ConvertTo-Json -Depth 8 [System.IO.File]::WriteAllText($outputPath, $json + [Environment]::NewLine, $utf8WithoutBom) Write-Host "Generated $($Definition.microphones.Count) microphones: $outputPath" } $rectangularFixtures = @( @{ Id = 'rectangular-2x2-450mm' Name = '2x2 sparse rectangular' Description = '4-channel uniform rectangular layout on the 0.45 m reference aperture' Columns = 2 Rows = 2 Width = 0.45 Height = 0.45 }, @{ Id = 'rectangular-4x3-450mm' Name = '4x3 sparse rectangular' Description = '12-channel uniform rectangular layout on the 0.45 m reference aperture' Columns = 4 Rows = 3 Width = 0.45 Height = 0.45 }, @{ Id = 'rectangular-8x6-450mm' Name = '8x6 rectangular' Description = '48-channel uniform rectangular layout on the 0.45 m reference aperture' Columns = 8 Rows = 6 Width = 0.45 Height = 0.45 }, @{ Id = 'rectangular-16x12' Name = '16x12 rectangular baseline' Description = '192-channel uniform rectangular layout on a 0.45 m square aperture' Columns = 16 Rows = 12 Width = 0.45 Height = 0.45 }, @{ Id = 'rectangular-24x16-450mm' Name = '24x16 dense rectangular' Description = '384-channel uniform rectangular layout on the 0.45 m reference aperture' Columns = 24 Rows = 16 Width = 0.45 Height = 0.45 }, @{ Id = 'rectangular-16x12-compact' Name = '16x12 compact rectangular' Description = '192-channel uniform rectangular layout on a 0.12 m square aperture' Columns = 16 Rows = 12 Width = 0.12 Height = 0.12 }, @{ Id = 'rectangular-16x12-large' Name = '16x12 large rectangular' Description = '192-channel uniform rectangular layout on a 1.20 m square aperture for spatial-aliasing comparison' Columns = 16 Rows = 12 Width = 1.2 Height = 1.2 } ) foreach ($fixture in $rectangularFixtures) { Write-ArrayFixture (New-RectangularArray @fixture) } $spiralMicrophones = [System.Collections.Generic.List[object]]::new() $microphoneCount = 192 $radius = 0.225 $goldenAngle = [Math]::PI * (3 - [Math]::Sqrt(5)) for ($index = 0; $index -lt $microphoneCount; $index++) { $microphoneRadius = $radius * [Math]::Sqrt(($index + 0.5) / $microphoneCount) $angle = $index * $goldenAngle $x = $microphoneRadius * [Math]::Cos($angle) $y = $microphoneRadius * [Math]::Sin($angle) $spiralMicrophones.Add([ordered]@{ id = 'mic-{0:D3}' -f ($index + 1) position = @([Math]::Round($x, 6), [Math]::Round($y, 6), 0) }) } $spiralDefinition = [ordered]@{ schemaVersion = '1.0.0' kind = 'micarrsim.array' id = 'fermat-spiral-192' name = '192-channel Fermat spiral' description = 'Equal-area Fermat spiral on a 0.45 m circular aperture for comparison with the rectangular baseline' units = 'm' coordinateSystem = New-CoordinateSystem aperture = [ordered]@{ width = 0.45; height = 0.45 } microphones = $spiralMicrophones } Write-ArrayFixture $spiralDefinition