Last active
August 9, 2024 05:24
-
-
Save Jaykul/01a0045e1551dffe6437bf63382c9813 to your computer and use it in GitHub Desktop.
Convert Nokia RTTL to VT256 DEC PS (PlaySound) escape sequences
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Convert-RTTTL { | |
<# | |
.SYNOPSIS | |
Convert Nokia RTTL to VT256 DEC PS (PlaySound) escape sequences for Windows Terminal, for instance. | |
.EXAMPLE | |
Convert-RTTTL 'Mario World Theme:d=4,o=5,b=125:a,8f.,16c,16d,16f,16p,f,16d,16c,16p,16f,16p,16f,16p,8c6,8a.,g,16c,a,8f.,16c,16d,16f,16p,f,16d,16c,16p,16f,16p,16a#,16a,16g,2f,16P,8a.,8f.,8c,8a.,f,16g#,16f,16c,16p,8g#.,2g,8a.,8f.,8c,8a.,f,16g#,16f,8c,2c6' -InformationAction Continue | |
Plays the Mario World Theme song (and show the name in the console). | |
.EXAMPLE | |
Convert-RTTTL 'HauntHouse: d=4,o=6,b=108: 2a5, 2e, 2d#, 2b5, 2a5, 2c, 2d, 2a#5, 2e., e, 1f5, 1a5, 1d#, 2e., d, 2c., b5, 1a5, 1p, 2a5, 2e, 2d#, 2b5, 2a5, 2c, 2d, 2a#5, 2e., e, 1f5, 1a5, 1d#, 2e., d, 2c., b5, 1a5' | Set-Clipboard | |
Converts the HauntHouse song to escape sequences and puts them on your clipboard, instead of playing it. | |
.LINK | |
https://en.wikipedia.org/wiki/Ring_Tone_Text_Transfer_Language | |
Thanks to GraphicHealer for the inspiration! | |
#> | |
param( | |
[Parameter(Mandatory)][string]$String, | |
[ValidateRange(0, 7)][int]$Volume = 3 | |
) | |
$Notes = @{ | |
"C5" = 1; "C#5" = 2; "D5" = 3; "D#5" = 4; "E5" = 5; "F5" = 6; "F#5" = 7; "G5" = 8; "G#5" = 9; "A5" = 10; "A#5" = 11; "B5" = 12 | |
"C6" = 13; "C#6" = 14; "D6" = 15; "D#6" = 16; "E6" = 17; "F6" = 18; "F#6" = 19; "G6" = 20; "G#6" = 21; "A6" = 22; "A#6" = 23; "B6" = 24 | |
"C7" = 25 | |
} | |
# Get Info and Settings for Song | |
$Title, $Defaults, $Song = $String -split ':' | |
Write-Information $Title | |
# D = Duration, B = BPM, O = Octave | |
$Default = $Defaults -split ',' | ConvertFrom-StringData | |
# Nokia RTTL specifies the tempo in beats per minute. | |
# VT520 DEC PS (PlaySound) specifies note duration in 1/32nds of a second. 60 * 32 = 1920 | |
$Adjustment = 32 / (1920 / 120) | |
$StringBuilder = [System.Text.StringBuilder]::new() | |
foreach ($Note in ($Song -split ',')) { | |
if (!($Note.Trim() -match "^(?<duration>\d+)?(?<note>[abcdefgp]#?)(?:(?<dot>\.)?|(?<octave>\d)?)*$")) { | |
Write-Error "Not a valid note: $Note" | |
} | |
$Note = $Matches.Note | |
$Duration = (32 / ($Matches.Duration ?? $Default.D)) * $Adjustment | |
if ($Matches.Dot) { | |
$Duration *= 1.5 | |
} | |
$Octave = $Matches.Octave ?? $Default.O | |
if (($Octave -notin 5, 6) -and -Not ($Octave -eq 7 -and $Note -eq "C")) { | |
Write-Error "Note out of range. Only C5..C7 are supported." | |
} | |
if ($Duration -ne $PreviousDuration) { | |
if ($StringBuilder.Length -gt 0) { | |
$null = $StringBuilder.Append(",~") | |
} | |
$null = $StringBuilder.Append("$([char]27)[$Volume;$Duration") | |
} elseif(!$PreviousDuration) { | |
$null = $StringBuilder.Append("$([char]27)[$Volume;$Duration") | |
} | |
$null = $StringBuilder.Append(";" + $Notes["$Note$Octave"]) | |
$PreviousDuration = $Duration | |
} | |
if ($StringBuilder.Length -gt 0) { | |
$null = $StringBuilder.Append(",~") | |
$StringBuilder.ToString() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment