LoginSignup
1
1

More than 5 years have passed since last update.

PowerShellでwaveファイルを作成したときに、System.IO.BinaryWriter の Write オーバーロードでやらかしたこと

Posted at

BinaryWriter Class (System.IO) | Microsoft Docs

BinaryWriterは標準ライブラリにあるので、すぐ使えて便利ですが、ミスをしてしまいました。
こんな風に書くと16ビットではなく32ビット書き込まれてしまいました。

$bw.Write([int16]2 * 1)

そうならないように

$bw.Write([int16](2 * 1))

括弧でくくっています。

ファイルにwavファイルを書く例

. .\wave.ps1; $fs=[System.IO.File]::Create($pwd.Path+"\r.wav"); WriteWave($fs); $fs.Close();
wave.ps1
function WriteWave(
    [System.IO.Stream]$os
) {
    $bw = [System.IO.BinaryWriter]::new($os)
    $os.Position = 0
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("RIFF"))
    $os.Position = 8
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("WAVE"))
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("fmt "))

    $bw.Write([int32](16))
    $bw.Write([int16](1))
    $bw.Write([int16](1)) # 1モノラル 2ステレオ
    $bw.Write([int32](44100)) # 周波数
    $bw.Write([int32](44100 * 2 * 1)) # 44.1kHz 16bit モノラル

    $bw.Write([int16](2 * 1)) # 括弧ないと32ビット書かれる
    $bw.Write([int16](16))
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("data"))

    $samples = 44100 * 2; # 周波数 * 秒
    $size = $samples * 1 * 2  # 周波数 * 1モノラル * 16bit
    $bw.Write([int32]($size));

    for ($i = 0; $i -lt $samples; $i += 1) {
        $v = Get-Random -Minimum -32768 -Maximum 32768
        $bw.Write([int16]($v))
    }

    $os.Position = 4
    $bw.Write([int32]($os.Length - 8)) # 括弧ないと64ビット書かれる
}

waveファイルのフォーマットはこれを参考にしました。
wav ファイルフォーマット

PowerShellでバイナリファイルを扱うとき、BinaryWriterはすぐに使えて便利ですが、書き込まれる長さに注意が必要です。

WriteI16 とか WriteI32 のような
メソッド名と書き込むビット数が一致するメソッドを作るのがありかもしれません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1