functions/utility/New-MiniGameSoundUtility.ps1
|
function New-MiniGameSoundUtility { <# .SYNOPSIS This return a utility class for playing sounds. .DESCRIPTION This return a utility class for playing sounds. .OUTPUTS .EXAMPLE Create a utility instance to print "Hello World" when the key "A" or "LetfArrow" is pressed. PS> $soundUtility = New-MiniGameRunUtility PS> $soundUtility.Add("name", "./path.wav") PS> $soundUtility.Play("name") .LINK #> [CmdletBinding()] param( [Parameter()] [switch] $Mute, # Load with example sounds. [Parameter()] [switch] $Example ) class MiniGameSoundUtilitySystemSounds { [void] Beep() { [System.Media.SystemSounds]::Beep.Play() } [void] Hand() { [System.Media.SystemSounds]::Hand.Play() } [void] Question() { [System.Media.SystemSounds]::Question.Play() } [void] Asterisk() { [System.Media.SystemSounds]::Asterisk.Play() } [void] Exclamation() { [System.Media.SystemSounds]::Exclamation.Play() } } class MiniGameSoundUtility { static [System.Boolean] $isWindows = $IsWindows [System.Boolean] $mute = $Mute.IsPresent [System.Object] $_initPlayer = $null [System.Object] $soundPlayers = @() [System.Collections.Hashtable] $jobs = @{} [System.Collections.Hashtable] $records = @{} [MiniGameSoundUtilitySystemSounds] $system = [MiniGameSoundUtilitySystemSounds]@{} static [MiniGameSoundUtility] Init() { $soundUtility = [MiniGameSoundUtility]@{} if (-NOT [MiniGameSoundUtility]::isWindows) { $soundUtility.mute = $true } else { Add-Type -AssemblyName "PresentationCore" for ($index = 0; $index -LT 20; $index++) { # Avoid parser errors with: [System.Windows.Media.MediaPlayer]::new() $soundUtility.soundPlayers += New-Object -TypeName System.Windows.Media.MediaPlayer } $soundUtility._initPlayer = New-Object -TypeName System.Windows.Media.MediaPlayer $soundUtility._initPlayer.Volume = 0 } return $soundUtility } <# Add sound files to use for playing or looping. #> [void] Add([System.String] $name, [System.IO.FileInfo] $file) { $this.Add($name, 1, $file) } [void] Add([System.String] $name, [System.Single] $volume, [System.IO.FileInfo] $file) { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows) { return } if (-NOT $file.Exists) { throw [System.InvalidOperationException]::new("Sound: '$file' was not found!") } $this.records.Remove($name) $this.records.Add($name, @{ file = $file.FullName Volume = $volume } ) $this._initPlayer.Open($file.FullName) $this._initPlayer.Position = [System.TimeSpan]::Zero $this._initPlayer.Play() } [void] Stop() { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows) { return } $this.jobs.Values | Stop-Job | Remove-Job for ($index = 0; $index -LT $this.soundPlayers.Count; $index++) { $this.soundPlayers[$index].Stop() } } [void] Stop([System.String] $sound) { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows) { return } if ($this.jobs.ContainsKey($sound)) { $this.jobs[$sound] | Stop-Job | Remove-Job $this.jobs.Remove($sound) } } [void] Play ([System.String] $sound, [System.Single] $volume) { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows) { return } if (-NOT $this.records.ContainsKey($sound)) { throw [System.InvalidOperationException]::new("'$sound' was not found!") } $soundData = $this.records[$sound] for ($index = 0; $index -LT $this.soundPlayers.Count; $index++) { $player = $this.soundPlayers[$index] if ( $player.Position.Ticks -EQ 0 -OR $player.NaturalDuration.TimeSpan.Ticks -EQ $player.Position.Ticks ) { $player.Open($soundData.file) $player.Volume = $soundData.Volume $player.Position = [System.TimeSpan]::Zero $player.Play() return } } } [void] Once ([System.String] $sound, [System.Single] $volume) { $this.Play($sound, $volume) } [void] Once([System.String] $sound) { $this.Play($sound, 1) } [void] Play ([System.String] $sound) { $this.Play($sound, 1) } [void] Loop([System.String] $sound) { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows -OR $this.jobs.ContainsKey($sound)) { return } if (-NOT $this.records.ContainsKey($sound)) { throw [System.InvalidOperationException]::new("'$sound' was not found!") } $soundLocation = $this.records[$sound].file $soundJob = Start-Job { $soundLocation = $using:soundLocation $soundPlayer = [System.Media.SoundPlayer]::new() $soundPlayer.SoundLocation = $soundLocation $soundPlayer.PlayLooping() Start-Sleep -Seconds 86400 } $this.jobs.Add($sound, $soundJob) } [void] Speak([System.String] $text) { if ($this.mute -OR -NOT [MiniGameSoundUtility]::isWindows) { return } $voice = New-Object -ComObject Sapi.spvoice $voice.Speak($text) } } if (-NOT $IsWindows) { Write-Warning "MiniGameSoundUtility is only supported on windows." } $soundUtility = [MiniGameSoundUtility]::Init() if ($Example.IsPresent) { $soundUtility.Add("snack", "$PSScriptRoot/../sounds/snake_snack.wav") $soundUtility.Add("music", "$PSScriptRoot/../sounds/snake_music.wav") } return $soundUtility } |