From bb2b556df900cf5f7838023116a83a4078e21f06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 05:43:16 +0000 Subject: [PATCH 1/2] Initial plan From 6091a9698d69a078a38617b6d9c577554312e5c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 05:49:40 +0000 Subject: [PATCH 2/2] Add PowerShell script to generate Vital presets from WAV files Co-authored-by: Godly75 <38914962+Godly75@users.noreply.github.com> --- scripts/win/README-vital-presets.md | 132 +++++++++++++ scripts/win/create-vital-presets.ps1 | 280 +++++++++++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100644 scripts/win/README-vital-presets.md create mode 100644 scripts/win/create-vital-presets.ps1 diff --git a/scripts/win/README-vital-presets.md b/scripts/win/README-vital-presets.md new file mode 100644 index 00000000000..462a7902fb9 --- /dev/null +++ b/scripts/win/README-vital-presets.md @@ -0,0 +1,132 @@ +# Vital Preset Generator Script + +## Overview + +`create-vital-presets.ps1` is a PowerShell script that automates the creation of Vital synthesizer presets from WAV files. It takes a template `.vital` preset file and generates individual presets for each WAV file found in a specified directory. + +## Features + +- Batch processing of multiple WAV files +- Uses a template preset as the base configuration +- Assigns WAV files to specified oscillator (1, 2, or 3) +- Generates properly formatted Vital preset files (.vital) +- Preserves original template settings while updating sample paths +- Color-coded console output for easy monitoring +- Comprehensive error handling and validation + +## Requirements + +- PowerShell 5.0 or higher +- Windows operating system +- A valid `.vital` template file +- Directory containing WAV files + +## Usage + +### Basic Syntax + +```powershell +.\create-vital-presets.ps1 -InitVital -WavFolder -OutputFolder +``` + +### Parameters + +| Parameter | Required | Description | +|-----------|----------|-------------| +| `-InitVital` | Yes | Path to the init.vital template file | +| `-WavFolder` | Yes | Path to folder containing WAV files | +| `-OutputFolder` | Yes | Path to output folder for generated presets | +| `-Oscillator` | No | Oscillator index (1-3) to assign samples to. Default: 1 | +| `-Help` | No | Display help information | + +### Examples + +**Basic usage:** +```powershell +.\create-vital-presets.ps1 -InitVital "C:\Templates\init.vital" -WavFolder "C:\Samples" -OutputFolder "C:\Presets" +``` + +**Using relative paths:** +```powershell +.\create-vital-presets.ps1 -InitVital ".\templates\init.vital" -WavFolder ".\samples" -OutputFolder ".\output" +``` + +**Assigning to oscillator 2:** +```powershell +.\create-vital-presets.ps1 -InitVital ".\init.vital" -WavFolder ".\wavs" -OutputFolder ".\presets" -Oscillator 2 +``` + +**Display help:** +```powershell +.\create-vital-presets.ps1 -Help +``` + +## How It Works + +1. **Validation**: The script validates that the init.vital file exists and is valid JSON +2. **Scanning**: Scans the specified folder for all `.wav` files +3. **Processing**: For each WAV file: + - Loads the template preset + - Updates the sample path for the specified oscillator + - Enables the oscillator + - Sets the preset name based on the WAV filename + - Saves the modified preset with a `.vital` extension +4. **Summary**: Displays a summary of successful and failed operations + +## File Structure + +The generated presets will: +- Be named after the WAV files (without extension) +- Include the full path to the WAV file in the preset +- Retain all other settings from the template +- Be saved in JSON format compatible with Vital + +## Tips + +- **Template Creation**: Create your ideal base preset in Vital and save it as your template file +- **WAV Organization**: Organize your WAV files by category in separate folders for easier batch processing +- **Multiple Oscillators**: Run the script multiple times with different oscillator numbers to assign samples to different oscillators +- **Backup**: Keep a backup of your template file before experimenting + +## Troubleshooting + +**"Init.vital file not found"** +- Verify the path to your template file is correct +- Use absolute paths if relative paths aren't working + +**"No WAV files found"** +- Ensure the folder path is correct +- Verify files have the `.wav` extension (case-sensitive on some systems) + +**"Invalid Vital preset file"** +- The template file must be valid JSON +- Open the file in Vital and re-save it if necessary + +**Permission errors** +- Run PowerShell as Administrator if you encounter permission issues +- Ensure the output folder is writable + +## Execution Policy + +If this is your first time running PowerShell scripts, you may need to set the execution policy: + +```powershell +Set-ExecutionPolicy -Scope CurrentUser RemoteSigned +``` + +## Related Scripts + +This script is similar in concept to the Python wavetable tools in `scripts/wt-tool/`: +- `wt-tool.py` - Creates Surge wavetables from WAV files +- Both scripts batch process audio files to create synthesizer assets + +## License + +This script is part of the Surge project and is licensed under GPL-3.0. + +## Support + +For issues or questions: +- Check the Surge project documentation +- Visit the Surge Synth Team forum +- Submit an issue on GitHub diff --git a/scripts/win/create-vital-presets.ps1 b/scripts/win/create-vital-presets.ps1 new file mode 100644 index 00000000000..78d56d485b5 --- /dev/null +++ b/scripts/win/create-vital-presets.ps1 @@ -0,0 +1,280 @@ +# create-vital-presets.ps1 +# +# A PowerShell script to create Vital synthesizer presets from WAV files +# This script takes an init.vital template file and generates separate +# Vital presets for each WAV file found in a specified directory. +# +# Usage: +# .\create-vital-presets.ps1 -InitVital "path\to\init.vital" -WavFolder "path\to\wavs" -OutputFolder "path\to\output" +# +# Requirements: +# - PowerShell 5.0 or higher +# - An init.vital template file +# - Directory containing WAV files + +Param( + [Parameter(Mandatory=$false, HelpMessage="Path to the init.vital template file")] + [string]$InitVital, + + [Parameter(Mandatory=$false, HelpMessage="Path to folder containing WAV files")] + [string]$WavFolder, + + [Parameter(Mandatory=$false, HelpMessage="Path to output folder for generated presets")] + [string]$OutputFolder, + + [Parameter(Mandatory=$false, HelpMessage="Oscillator index to assign sample to (1, 2, or 3)")] + [ValidateRange(1,3)] + [int]$Oscillator = 1, + + [switch]$Help +) + +function Show-Help { + Write-Host @" +create-vital-presets.ps1 - Generate Vital presets from WAV files + +DESCRIPTION: + This script reads an init.vital template file and creates separate Vital + synthesizer presets for each WAV file found in the specified folder. Each + generated preset will have the WAV file assigned as a sample source. + +PARAMETERS: + -InitVital + Path to the init.vital template file. This file serves as the base + preset configuration. + + -WavFolder + Path to the folder containing WAV files. All .wav files in this + folder will be processed. + + -OutputFolder + Path to the output folder where generated .vital presets will be saved. + The folder will be created if it doesn't exist. + + -Oscillator <1|2|3> + Oscillator index to assign the sample to. Valid values are 1, 2, or 3. + Default is 1 (oscillator 1). + + -Help + Display this help message. + +EXAMPLES: + .\create-vital-presets.ps1 -InitVital "C:\Templates\init.vital" -WavFolder "C:\Samples" -OutputFolder "C:\Output" + + .\create-vital-presets.ps1 -InitVital ".\init.vital" -WavFolder ".\wavs" -OutputFolder ".\presets" -Oscillator 2 + +NOTES: + - The init.vital file must be a valid Vital preset in JSON format + - WAV files should be compatible with Vital (mono or stereo, various sample rates supported) + - Generated preset names will be based on the WAV file names + - Existing files in the output folder with the same name will be overwritten + +"@ +} + +function Test-VitalFile { + param([string]$Path) + + if (-not (Test-Path $Path)) { + return $false + } + + try { + $content = Get-Content $Path -Raw + $json = $content | ConvertFrom-Json + return $true + } + catch { + return $false + } +} + +function Get-WavFiles { + param([string]$Path) + + if (-not (Test-Path $Path)) { + throw "WAV folder does not exist: $Path" + } + + $wavFiles = Get-ChildItem -Path $Path -Filter "*.wav" -File + return $wavFiles +} + +function New-VitalPreset { + param( + [string]$TemplateContent, + [string]$SamplePath, + [string]$PresetName, + [int]$OscillatorIndex + ) + + try { + # Parse the template JSON + $preset = $TemplateContent | ConvertFrom-Json + + # Determine the oscillator key name (osc_1, osc_2, or osc_3) + $oscKey = "osc_$OscillatorIndex" + + # Update the sample path for the specified oscillator + if ($preset.settings.PSObject.Properties.Name -contains $oscKey) { + # Set the sample source + $sampleKey = "sample" + if ($preset.settings.$oscKey.PSObject.Properties.Name -contains $sampleKey) { + $preset.settings.$oscKey.sample = $SamplePath + } + else { + # Add sample property if it doesn't exist + $preset.settings.$oscKey | Add-Member -NotePropertyName "sample" -NotePropertyValue $SamplePath -Force + } + + # Enable the oscillator + $onKey = "${oscKey}_on" + if ($preset.settings.PSObject.Properties.Name -contains $onKey) { + $preset.settings.$onKey = 1 + } + else { + $preset.settings | Add-Member -NotePropertyName $onKey -NotePropertyValue 1 -Force + } + + # Set oscillator to sample mode (typically value 5 or 6 for sample playback) + $waveKey = "${oscKey}_wave_frame" + if ($preset.settings.PSObject.Properties.Name -contains $waveKey) { + # Keep existing wave_frame value or set to sample mode + } + } + else { + Write-Warning "Oscillator $OscillatorIndex not found in template. Adding basic configuration." + # Add a basic oscillator configuration + $preset.settings | Add-Member -NotePropertyName $oscKey -NotePropertyValue @{ + "sample" = $SamplePath + } -Force + $preset.settings | Add-Member -NotePropertyName "${oscKey}_on" -NotePropertyValue 1 -Force + } + + # Update preset name if the property exists + if ($preset.PSObject.Properties.Name -contains "preset_name") { + $preset.preset_name = $PresetName + } + elseif ($preset.PSObject.Properties.Name -contains "name") { + $preset.name = $PresetName + } + else { + $preset | Add-Member -NotePropertyName "preset_name" -NotePropertyValue $PresetName -Force + } + + # Update author and comments if desired + if ($preset.PSObject.Properties.Name -contains "author") { + $preset.author = "$($preset.author) + Surge Script" + } + + # Convert back to JSON with proper formatting + $outputJson = $preset | ConvertTo-Json -Depth 100 + + return $outputJson + } + catch { + throw "Error creating preset: $_" + } +} + +function Main { + # Show help if requested or if required parameters are missing + if ($Help -or [string]::IsNullOrEmpty($InitVital) -or [string]::IsNullOrEmpty($WavFolder) -or [string]::IsNullOrEmpty($OutputFolder)) { + Show-Help + if (-not $Help) { + Write-Host "" + Write-Error "Missing required parameters. Please provide -InitVital, -WavFolder, and -OutputFolder" + } + return + } + + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "Vital Preset Generator from WAV Files" -ForegroundColor Cyan + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "" + + # Validate init.vital file + Write-Host "Validating init.vital file..." -ForegroundColor Yellow + if (-not (Test-Path $InitVital)) { + Write-Error "Init.vital file not found: $InitVital" + return + } + + if (-not (Test-VitalFile $InitVital)) { + Write-Error "Invalid Vital preset file: $InitVital" + return + } + + Write-Host "✓ Init.vital file is valid" -ForegroundColor Green + + # Load template content + $templateContent = Get-Content $InitVital -Raw + + # Get WAV files + Write-Host "Scanning for WAV files..." -ForegroundColor Yellow + try { + $wavFiles = Get-WavFiles -Path $WavFolder + } + catch { + Write-Error $_ + return + } + + if ($wavFiles.Count -eq 0) { + Write-Warning "No WAV files found in: $WavFolder" + return + } + + Write-Host "✓ Found $($wavFiles.Count) WAV file(s)" -ForegroundColor Green + Write-Host "" + + # Create output folder if it doesn't exist + if (-not (Test-Path $OutputFolder)) { + Write-Host "Creating output folder: $OutputFolder" -ForegroundColor Yellow + New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null + } + + # Process each WAV file + $successCount = 0 + $errorCount = 0 + + foreach ($wavFile in $wavFiles) { + $presetName = [System.IO.Path]::GetFileNameWithoutExtension($wavFile.Name) + $outputFile = Join-Path $OutputFolder "$presetName.vital" + + Write-Host "Processing: $($wavFile.Name)" -ForegroundColor Cyan + Write-Host " → Creating preset: $presetName.vital" -ForegroundColor Gray + + try { + # Create the preset with the WAV file path + $presetJson = New-VitalPreset -TemplateContent $templateContent ` + -SamplePath $wavFile.FullName ` + -PresetName $presetName ` + -OscillatorIndex $Oscillator + + # Save the preset + $presetJson | Out-File -FilePath $outputFile -Encoding UTF8 -Force + + Write-Host " ✓ Saved: $outputFile" -ForegroundColor Green + $successCount++ + } + catch { + Write-Error " ✗ Failed to create preset: $_" + $errorCount++ + } + + Write-Host "" + } + + # Summary + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "Summary:" -ForegroundColor Cyan + Write-Host " Total WAV files: $($wavFiles.Count)" -ForegroundColor White + Write-Host " Successful: $successCount" -ForegroundColor Green + Write-Host " Failed: $errorCount" -ForegroundColor $(if ($errorCount -gt 0) { "Red" } else { "White" }) + Write-Host " Output folder: $OutputFolder" -ForegroundColor White + Write-Host "========================================" -ForegroundColor Cyan +} + +# Run the main function +Main