Types/Wave/get_Chunk.ps1
|
<# .SYNOPSIS Get Wave Chunks .DESCRIPTION Wave files are stored in chunks. Gets the chunks within a wave file. .NOTES When this property is first enumerated, it will add additional properties for each trimmed chunk name and their start * `$this.#data` will contain the `data` chunk bytes * `$this.#data.start` will contain the `data` chunk start * `$this.#fmt` will contain the format `fmt ` chunk bytes * `$this.#fmt.start` will contain the `fmt ` chunk start Additional chunks are optional. .LINK https://en.wikipedia.org/wiki/WAV#WAV_file_header .LINK https://en.wikipedia.org/wiki/Resource_Interchange_File_Format #> # If this has chunks, return them if ($this.'#Chunk') { return $this.'#Chunk'} # If this is not a stream, we can't read it. if ($this -isnot [IO.Stream]) { return } # If this cannot read or seek, we can't read it. if (-not ($this.CanRead -or $this.CanSeek)) { return } # Create a binary reader $binaryReader = [IO.BinaryReader]::new($this) # seek to zero $this.Position = 0 # RIFF should be the first four characters $riff = $binaryReader.ReadChars(4) -join '' # If that is not the case, it is not a wave if ($riff -cne 'RIFF') { throw "Not a Wave (no RIFF header)" } # The next four bytes are the wave file size. # We do not actually care about this right now, and other properties will reveal it. $null = $binaryReader.ReadUInt32() # Followed by the four character File Format ID $fileFormatId = $binaryReader.ReadChars(4) -join '' # Which must be `WAVE` if ($fileFormatId -cne 'WAVE') { throw "Not a Wave (incorrect file format id: $fileFormatID)" } # While we have no reached the end of the stream $chunks = @(while ($this.Position -lt $this.Length) { # Note the chunk start $chunkStart = $this.Position $chunk = [Ordered]@{ start = $chunkStart # then get the ID id = $binaryReader.ReadChars(4) -join '' # and the length length = $binaryReader.ReadUInt32() } if (-not $chunk.id) { throw "Malformed Chunks (no must have ID)" } # Initialize an array to hold the length $chunk.data = [byte[]]::new($chunk.length) # and read the chunk $null = $this.Read($chunk.data, 0, $chunk.Length) # Then cache the chunk and it's start into note properties. $this | Add-Member NoteProperty "#$($chunk.id.Trim())" $chunk.data -Force $this | Add-Member NoteProperty "#$($chunk.id.Trim()).start" $chunk.start -Force # and emit the chunk. $chunk }) # Reset our position to zero. $this.Position = 0 # cache the chunks $this | Add-Member NoteProperty '#Chunk' $chunks -Force # and return the chunks. return $chunks |