Skip to content

Instantly share code, notes, and snippets.

@fukuroder
Last active March 3, 2017 15:45
Show Gist options
  • Select an option

  • Save fukuroder/3c47ed87e2322ca9dc4b to your computer and use it in GitHub Desktop.

Select an option

Save fukuroder/3c47ed87e2322ca9dc4b to your computer and use it in GitHub Desktop.
Low-pass filter with Windows PowerShell
# create lowpass filter
function create_lowpass_filter(
[double]$samplerate,
[double]$cutoff_freq,
[double]$resonance)
{
# a0 + a1*z^-1 + a2*z^-2
# H(z) = ------------------------
# 1 + b1*z^-1 + b2*z^-2
$s = [Math]::Tan($cutoff_freq*3.14159265/$samplerate)
$t = $s/$resonance
$u = $s*$s + $t + 1.0
$a0 = $s*$s/$u
$a1 = 2.0*$s*$s/$u
$a2 = $s*$s/$u
$b1 = 2.0*($s*$s - 1.0)/$u
$b2 = ($s*$s - $t + 1.0)/$u
return @{
a0 = $a0; a1 = $a1; a2 = $a2; b1 = $b1; b2 = $b2;
in_z = 0.0; in_zz = 0.0; out_z = 0.0; out_zz = 0.0}
}
# filter execute
function filter_execute($f, [double]$in)
{
$denormal_canceler = 1.0e-100
$out = $f.a0*$in + $f.a1*$f.in_z + $f.a2*$f.in_zz - $f.b1*$f.out_z - $f.b2*$f.out_zz
$f.in_zz = $f.in_z + $denormal_canceler
$f.in_z = $in + $denormal_canceler
$f.out_zz = $f.out_z + $denormal_canceler
$f.out_z = $out + $denormal_canceler
return $out
}
# SoX .dat format example
#
#; Sample Rate 48000
#; Channels 2
# 0 -0.45745626 -0.45745626
# 2.0833333e-05 -0.3917995 -0.3917995
# 4.1666667e-05 -0.067243849 -0.06724384
# 6.25e-05 0.32710202 0.32710202
# ... ... ...
# parameter
$cutoff_freq = 1000.0
$resonance = 0.70710678118
# read header
$reader = [System.IO.File]::ReadLines("in.dat")
$header = $reader | select -First 2
$samplerate, $channels = $header | foreach { (-split $_)[-1] }
if($channels -ne 2){ return }
# create filter
$f1 = create_lowpass_filter $samplerate $cutoff_freq $resonance
$f2 = create_lowpass_filter $samplerate $cutoff_freq $resonance
# start
$writer = [System.IO.File]::CreateText("out.dat")
$header | foreach { $writer.WriteLine($_) }
$reader `
| foreach { ,(-split $_) } `
| foreach { $_[0] + " " + (filter_execute $f1 $_[1]) + " " + (filter_execute $f2 $_[2]) } `
| foreach { $writer.WriteLine($_) }
$writer.Close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment