著者:斉藤 博文
プログラミング言語「AWK」は、データストリーム(データの流れ)を逐次処理するのに適しています。本連載では、電子回路の分野でその特徴を生かし、シェルスクリプトを組み合わせてデジタル信号を処理します。第2回は、高周波ノイズを除去する「ローパスフィルタ」について解説します。
シェルスクリプトマガジン Vol.80は以下のリンク先でご購入できます。
図6 移動平均のプログラム(lpf.awk)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#! /usr/bin/gawk -f BEGIN { # define number of order num_ord = num_ord ? num_ord : 7; # define length of ring buffers len_data_raw = num_ord + 1; len_data_lpf = 2; # initialize ring buffers for (i = 0; i < len_data_raw; i++) { arr_data_raw[i] = 0.0; } for (i = 0; i < len_data_lpf; i++) { arr_data_lpf[i] = 0.0; } # initialize index of ring buffers idx_data_raw = 0; idx_data_lpf = 0; # initialize number of data num_data_raw = 0; } { # add number of data num_data_raw++; # update index of ring buffers (write pointers) idx_data_raw = num_data_raw % len_data_raw; idx_data_lpf = num_data_raw % len_data_lpf; # clear number of data if (idx_data_raw == 0 && idx_data_lpf == 0) { num_data_raw = 0; } # store input raw data val_data_raw = $0; arr_data_raw[idx_data_raw] = val_data_raw; # apply low pass filter arr_data_lpf[idx_data_lpf] = lpf( \ arr_data_raw, arr_data_lpf, idx_data_raw, idx_data_lpf, num_ord, len_data_raw, len_data_lpf); # print results print arr_data_lpf[idx_data_lpf]; } |
図10 ずれ補正を加えた移動平均のプログラム(lpf_gd.awk)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#! /usr/bin/gawk -f BEGIN { # define number of order num_ord = num_ord ? num_ord : 7; # define group delay val_gd = int((num_ord - 1) / 2); # define length of ring buffers len_data_raw = num_ord + 1; len_data_lpf = val_gd + 1; # initialize ring buffers for (i = 0; i < len_data_raw; i++) { arr_data_raw[i] = 0.0; } for (i = 0; i < len_data_lpf; i++) { arr_data_lpf[i] = 0.0; } # initialize index of ring buffers idx_data_raw = 0; idx_data_lpf = 0; # initialize number of data num_data_raw = 0; } { # add number of data num_data_raw++; # update index of ring buffers (write pointers) idx_data_raw = num_data_raw % len_data_raw; idx_data_lpf = num_data_raw % len_data_lpf; # clear number of data if (idx_data_raw == 0 && idx_data_lpf == 0) { num_data_raw = 0; } # store input raw data val_data_raw = $0; arr_data_raw[idx_data_raw] = val_data_raw; # apply low pass filter arr_data_lpf[idx_data_lpf] = lpf( \ arr_data_raw, arr_data_lpf, idx_data_raw, idx_data_lpf, num_ord, len_data_raw, len_data_lpf); # print results print get_buffer(arr_data_raw, idx_data_raw - val_gd, len_data_raw), arr_data_lpf[idx_data_lpf]; } # get value of ring buffer function get_buffer(arr, idx, len) { if (idx < 0) { return arr[idx + len]; } return arr[idx]; } # low pass filter function lpf(arr_x, arr_y, idx_x, idx_y, ord, len_x, len_y, _ret, _gain) { _ret = 0.0; _gain = 1.0 / ord; _ret += get_buffer(arr_y, idx_y - 1, len_y); _ret += _gain * get_buffer(arr_x, idx_x, len_x); _ret -= _gain * get_buffer(arr_x, idx_x - ord, len_x); return _ret; } |