SciLabによるPSN SSB

sdr-japanのほうにアップロードしたのですが、SciLabによるSSBのスクリプトを書きました。AFを複素フィルタで処理して音声信号から負の周波数成分を取り除く部分です。出力は複素信号です。

function [y]=psnssb(x)
// PSN style SSB generator  for SciLab
// by Suikan. 2006

  [r, c] = size(x)
 
// create 0..1.2kHz  LPF at 48kSamples/sec
  taps = 511;
  hn=eqfir( taps, [0 1.2/48; 1.5/48 0.5], [1 0], [0.01 1] );

// make filter as +300Hz ..+3kHz complex filter. By + 1.5kHz oscillator
  thn = (hn .* exp(%i*[1:taps]*2*%pi*1.5/48))';

  y = [0 0];
// Do complex LPF (complex BPF) by FIR filter
  for k=1:1:c-taps;
    y(1,k+taps) = x(k:(k+taps-1)) * thn;
  end

endfunction

いやはや、簡単簡単。複素信号を使うと本当にすっきり書けます。一方で、Write-Only-Languageくささが強いです。私の腕の悪さが大きいですが、数値計算系のインタープリター言語の特徴かもしれません。APL、あれは個性的でした。
全体の流れとしては、

  1. 実数LPFを作る
  2. そのフィルタに+1.5kHzの複素回転子を作用させ、中心周波数+1.5kHzのBPFにする。
  3. 入力信号をフィルタに通す

と、これだけです。簡潔なのですが、FIRフィルタを実行する関数がないのはSciLabの不思議なところです。
フィルタのタップ数が511点とバカ長いですが、倍精度浮動小数点演算なので、このくらい長くしても効きます。しかし信号が3kHzまでなのですから、本来なら1/4デシメーターで落として処理するべきですね。