Compress-IRCodes.ps1


May 1, 2026


param (
    [Parameter(Mandatory=$true)]
    [string]$InputFile,

    [Parameter(Mandatory=$false)]
    [string]$OutputFile = "output_codes_optimized.h"
)

if (-not (Test-Path $InputFile)) {
    Write-Error "Input file '$InputFile' not found."
    exit
}

$lines = Get-Content $InputFile | Where-Object { $_.Trim() -ne "" }

$allCodesNames = @()
$codeLengths = @()
$baseUnits = @()
$outputContent = @()

$outputContent += "// --------------------------------------------------------"
$outputContent += "// OPTIMIZED IR CODES (8-bit Multipliers)"
$outputContent += "// --------------------------------------------------------"
$outputContent += ""

$index = 0

foreach ($line in $lines) {
    # Extract numbers
    $matches = [regex]::Matches($line, '\d+')
    $numbers = $matches | ForEach-Object { [uint32]$_.Value }
    
    $length = $numbers.Count
    if ($length -eq 0) { continue }

    # Find the base unit (minimum non-zero value, typically the standard pulse width)
    $validNumbers = $numbers | Where-Object { $_ -gt 0 }
    $baseUnit = ($validNumbers | Measure-Object -Minimum).Minimum
    $baseUnits += $baseUnit
    $codeLengths += $length

    $compressedNumbers = @()
    foreach ($num in $numbers) {
        # Calculate the multiplier
        $multiplier = [math]::Round($num / $baseUnit)
        
        # Prevent uint8_t overflow (max 255)
        if ($multiplier -gt 255) {
            Write-Warning "Code c$index has a trailing pause that exceeds 8-bit limits. Capping at 255."
            $multiplier = 255
        }
        $compressedNumbers += $multiplier
    }

    $arrayName = "c$index"
    $allCodesNames += $arrayName

    $formattedNumbers = $compressedNumbers -join ", "
    
    # Notice we are now using uint8_t instead of uint16_t!
    $outputContent += "const uint8_t ${arrayName}[] PROGMEM = {$formattedNumbers};"
    $outputContent += ""

    $index++
}

$outputContent += "// --------------------------------------------------------"
$outputContent += "// MASTER TABLES"
$outputContent += "// --------------------------------------------------------"
$outputContent += ""

# Format master pointer array (Now pointing to uint8_t)
$allCodesStr = $allCodesNames -join ", "
$outputContent += "const uint8_t* const allCodes[] PROGMEM = {$allCodesStr};"
$outputContent += ""

# Format base units array (This stores the base timing for each code)
$baseUnitsStr = $baseUnits -join ", "
$outputContent += "const uint16_t baseUnits[] = {$baseUnitsStr}; // Base microsecond multiplier per code"
$outputContent += ""

# Format lengths array
$lengthsStr = $codeLengths -join ", "
$outputContent += "const uint8_t codeLengths[] = {$lengthsStr}; // Number of values in each array"
$outputContent += ""

$outputContent += "const uint8_t totalCodes = $index;"

$outputContent | Set-Content $OutputFile
Write-Host "Successfully generated OPTIMIZED codes in '$OutputFile'!" -ForegroundColor Green