The definitive solution for audio device renumbering issues in iRacing and SimHub
Tired of iRacing and SimHub losing your audio settings every time Windows renumbers your devices? SimAudioFixer creates a stable "fingerprint" for each device and automatically updates configurations when GUIDs change.
- Smart Detection: Identifies devices by hardware ID (VID/PID), not by temporary GUID
- Automatic Updates: Patches
app.ini(iRacing) andShakeITBassShakersSettingsV2.json(SimHub) - Active Monitoring: FileSystemWatcher detects when iRacing/SimHub modify files
- Notifications: Alerts you and asks if you want to reapply your configuration
- Dark Mode: Fully dark interface so you don't get blinded at 3 AM
- Auto Start: Option to run silently at Windows startup (no UAC prompts!)
- Automatic Backup: Saves a backup before modifying files
- Download
SimAudioFixer-Setup.msifrom Releases - Run the installer (requires administrator privileges)
- Launch SimAudioFixer from the Start Menu or Desktop shortcut
- Optionally enable "Run at Windows startup" from the tray icon menu
-
Clone and build:
git clone https://github.com/xilonoide/SimAudioFixer.git cd SimAudioFixer dotnet build SimAudioFixer.Installer -c Release -
The MSI installer will be at:
SimAudioFixer.Installer\bin\Release\SimAudioFixer-Setup.msi
SimAudioFixer requires administrator privileges because:
- SimHub is typically installed in
C:\Program Files (x86)\which requires admin access to modify - The app will show a UAC prompt when launched manually
- Auto-start runs without UAC prompts using Windows Task Scheduler with pre-authorized elevated privileges
- Open SimAudioFixer from the desktop icon or system tray (accept UAC prompt)
- Go to the Soundcards tab to see your detected devices
- In the iRacing tab:
- Select the folder where
app.iniis located (if not in the default path) - Assign each device to its role (Main, Spotter, LFE, etc.)
- Press "Save Configuration"
- Select the folder where
- In the SimHub tab:
- Select the folder where
ShakeITBassShakersSettingsV2.jsonis located - Assign the device for Bass Shaker
- Press "Save Configuration"
- Select the folder where
- Press "Apply Changes" to patch the files
SimAudioFixer runs in the system tray. Right-click the icon to:
- Apply Changes: Force manual update
- Configure Devices: Open the main window
- Run at Windows startup: Enable/disable auto start
- Exit: Close the application
To run without interface (ideal for scripts or startup):
SimAudioFixer.exe initThis applies all configured patches immediately and exits.
The core innovation of SimAudioFixer is the stable device fingerprint. Instead of relying on Windows GUIDs (which change unpredictably), we create a composite identifier:
Fingerprint = SHA256(HardwareId + "_" + DataFlow)
Components:
- HardwareId: USB vendor and product identifier (e.g.,
VID_1234&PID_5678) - DataFlow: Whether the device is for rendering (output) or capture (input)
This fingerprint remains stable across:
- Windows reboots
- Driver updates
- Windows updates that renumber devices
┌─────────────────────────────────────────────────────────────┐
│ SimAudioFixer.WPF │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ ViewModels │ │ Views │ │ Services │ │
│ │ - Main │ │ - MainWindow│ │ - TrayIconService │ │
│ │ - Soundcards│ │ - Tabs │ │ - StartupManager │ │
│ │ - iRacing │ │ - DarkTheme │ │ (Task Scheduler) │ │
│ │ - SimHub │ │ │ │ - DarkMessageBox │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SimAudioFixer.Core │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Models │ │ Services │ │ Utils │ │
│ │ - AudioDev │ │ - Scanner │ │ - IniFileParser │ │
│ │ - Fingerpr │ │ - Mapper │ │ - BackupManager │ │
│ │ - Mapping │ │ - Patchers │ │ │ │
│ │ - Config │ │ - Watcher │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- Scan:
NAudioDeviceScannerqueries Windows Audio API (WASAPI) - Fingerprint:
AudioDeviceFingerprintcreates stable identifiers - Map:
AudioDeviceMapperassociates fingerprints with roles (Main, Spotter, etc.) - Patch:
IracingConfigPatcher/SimHubConfigPatcherupdate config files - Watch:
FileWatcherServicemonitors for external changes - Notify:
TrayIconServiceshows balloon notifications to alert user
- .NET 8 SDK
- Visual Studio 2022 or Rider
git clone https://github.com/xilonoide/SimAudioFixer.git
cd SimAudioFixer
dotnet restore
dotnet builddotnet test114 tests covering all core functionality:
- Models: AudioDevice, AudioDeviceFingerprint, DeviceMapping, AppConfiguration
- Services: AudioDeviceMapper, IracingConfigPatcher, SimHubConfigPatcher
- Utils: IniFileParser, BackupManager
- EndToEndPatchingTests: Full workflow testing for iRacing and SimHub patching
- FileWatcherIntegrationTests: File monitoring, debouncing, pause/resume functionality
All tests use:
- xUnit as the test framework
- FluentAssertions for readable assertions
- Moq for mocking dependencies
- coverlet.collector for code coverage
SimAudioFixer/
├── SimAudioFixer.Core/ # Business logic (no UI dependencies)
│ ├── Models/
│ │ ├── AudioDevice.cs # Represents an audio device
│ │ ├── AudioDeviceFingerprint.cs # Stable device identifier
│ │ ├── DeviceMapping.cs # Role-to-device association
│ │ └── AppConfiguration.cs # App settings persistence
│ ├── Services/
│ │ ├── IAudioDeviceScanner.cs # Interface for device scanning
│ │ ├── NAudioDeviceScanner.cs # NAudio implementation
│ │ ├── AudioDeviceMapper.cs # Manages device-role mappings
│ │ ├── IConfigPatcher.cs # Interface for config patchers
│ │ ├── IracingConfigPatcher.cs # Patches iRacing app.ini
│ │ ├── SimHubConfigPatcher.cs # Patches SimHub JSON
│ │ └── FileWatcherService.cs # Monitors config file changes
│ └── Utils/
│ ├── IniFileParser.cs # INI file read/write
│ └── BackupManager.cs # Backup creation/restoration
│
├── SimAudioFixer.WPF/ # WPF UI application
│ ├── ViewModels/ # MVVM ViewModels
│ ├── Views/ # XAML views
│ ├── Services/
│ │ ├── TrayIconService.cs # System tray icon and notifications
│ │ ├── StartupManager.cs # Task Scheduler integration
│ │ └── DarkMessageBox.cs # Themed message boxes
│ ├── Themes/
│ │ └── DarkTheme.xaml # Dark mode styles
│ └── app.manifest # UAC elevation manifest
│
├── SimAudioFixer.Tests/ # xUnit test project
│ ├── UnitTests/ # Unit tests for Core
│ └── IntegrationTests/ # End-to-end tests
│
└── SimAudioFixer.Installer/ # WiX installer project
├── SimAudioFixer.Installer.wixproj # WiX project file
├── Package.wxs # Installer definition
├── Assets/
│ └── icon.ico # Application icon
└── README.md # Installer build instructions
To create the MSI installer:
dotnet build SimAudioFixer.Installer -c ReleaseOutput: SimAudioFixer.Installer\bin\Release\SimAudioFixer-Setup.msi (~51 MB)
This automatically builds and publishes the WPF application first.
The application is self-contained - it includes the entire .NET 8 runtime, so users don't need to install anything else.
See SimAudioFixer.Installer/README.md for more details on the installer project.
-
Self-Contained Deployment: The application includes the entire .NET 8 runtime (~156 MB), eliminating dependency issues and simplifying installation.
-
Task Scheduler for Auto-Start: Instead of the Startup folder, we use Windows Task Scheduler with "Run with highest privileges" to avoid UAC prompts on every Windows boot.
-
Static FileWatcherService.Current: Allows ViewModels to pause file watching during their own writes, preventing infinite loops.
-
Fingerprint-based Mapping: Device roles are stored with fingerprints, not GUIDs, ensuring mappings survive device renumbering.
-
Backup Before Patch: Every config modification is preceded by a backup, allowing recovery if something goes wrong.
-
Embedded Resources: The application icon is embedded as a manifest resource, ensuring it works correctly in single-file deployments.
Contributions are welcome! Please:
- Fork the repository
- Create a branch for your feature (
git checkout -b feature/AmazingFeature) - Write tests for new functionality
- Ensure all tests pass (
dotnet test) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Use meaningful variable and method names
- Add XML documentation comments to public methods
- Follow MVVM pattern for WPF code
- Keep Core layer free of UI dependencies
- File:
%USERPROFILE%\Documents\iRacing\app.ini - Section:
[Audio] - Keys:
devSpeakerId,devSPCCId,devLFEId,devMicrophoneId,devVoiceChatId(and their correspondingNamevalues)
- File:
C:\Program Files (x86)\SimHub\PluginsData\Common\ShakeITBassShakersSettingsV2.json - JSON Path:
OutputManager.ChannelsSettingsV3[0] - Fields:
Name,OutputId,InstanceId,HardwareID1/2/3
- Make sure devices are connected and recognized by Windows
- Only WASAPI-compatible devices are detected
- Try refreshing devices with the "Refresh Devices" button
- SimHub must be closed before applying changes
- If you get "Access Denied", make sure you accepted the UAC prompt
- The app needs administrator privileges to write to Program Files
- iRacing must be closed before applying changes
- Check that the app.ini file is not read-only
- Check that Windows notifications are enabled for SimAudioFixer
- Verify "Focus Assist" is not blocking notifications
- Open Task Scheduler and verify "SimAudioFixer" task exists
- Check that the task is set to "Run with highest privileges"
- Try disabling and re-enabling "Run at Windows startup"
- This should NOT happen if auto-start is configured correctly
- The Task Scheduler method should bypass UAC
- If it still happens, recreate the startup configuration
This project is licensed under the MIT License - see the LICENSE file for details.
This project is built with these amazing libraries:
- NAudio - Audio device enumeration and WASAPI support
- CommunityToolkit.Mvvm - MVVM framework and helpers
- Hardcodet.NotifyIcon.Wpf - System tray icon support
- Microsoft.Toolkit.Uwp.Notifications - Windows toast notifications
Special thanks to:
- The iRacing and SimHub communities for inspiration and feedback
- All contributors and testers
Like this project? Give it a star on GitHub!
Made with ❤️ for the simracers community
