EmptyProjectを使う その10 (FFTで周波数shift) DATA->capture_fft[2*i]=DATA->capture_fft[8192-2*tune+2*i]; } } for(i=0;i<tune;i++) } } } next_stage: //DATA->capture_fft[2*i] int offset; info mode_48KHz_lsb= {1,0,1,2700,1,0,IDC_RADIO1LSB,IDC_RADIO2BW2700}; info mode_96KHz_cwl= {1,0,1,2200,800,-7680,IDC_RADIO1CWL,IDC_RADIO2BW2200}; info mode_96KHz_lsb= {1,0,1,2700,1,0,IDC_RADIO1LSB,IDC_RADIO2BW2700}; info
info_array[6]={mode_48KHz_lsb,mode_48KHz_usb,mode_96KHz_cwl,mode_96KHz_cwu, ............................................................................................................................................................................................................................................................. info_array[0]=&mode_48KHz_lsb;
下の小窓は、outputをFFTして、その結果を表示しています。(CWの音と比較して、見苦しくない程度の遅延)
1.FFTを使って、周波数shiftする
' A Software
Defined Radio for the Masses '
を読んで、
FFFTの結果を並べ替えて、結果的に、周波数shiftする事を、学びました。
何たる発想の転換やっ!
その効果は、素晴らしいものがあります。
しかも、
0HzにあるLow
Pass
Filterを、FFTしたものと、掛け合わせて、それから、その結果を、IFFTするのですから、
LPFの帯域幅だけ、pickupして、ここだけ、周波数を並べ替えてやれば済みます。
//ここで、tuneで、周波数遷移する
//DATA->capture_fft
の一部分だけを変化して同調する span幅だけ、0Hzへ copyする
if(tune>0)
{
if(
tune>span
)
{
for(i=0;i<tune-span;i++)
{
DATA->capture_fft[-2*tune+2*i]=DATA->capture_fft[-2*tune+2*i+1]=0.0;
}
for(i=0;i<span;i++)
{
DATA->capture_fft[2*i+1]=DATA->capture_fft[8192-2*tune+2*i+1];
goto
next_stage;
}
if(tune<=span)
{
for(i=0;i<span-tune;i++)
{
dummy[2*(i+tune)]=DATA->capture_fft[2*i];
dummy[2*(i+tune)+1]=DATA->capture_fft[2*i+1];
{
dummy[2*i]=DATA->capture_fft[8192-2*tune+2*i];
dummy[2*i+1]=DATA->capture_fft[8192-2*tune+2*i+1];
for(i=0;i<span;i++)
{
DATA->capture_fft[2*i]=dummy[2*i];
DATA->capture_fft[2*i+1]=dummy[2*i+1];
}
goto
next_stage;
}
else
{
for(i=0;i<span;i++)
{
DATA->capture_fft[2*i]=DATA->capture_fft[2*i-2*tune];
DATA->capture_fft[2*i+1]=DATA->capture_fft[2*i-2*tune+1];
DATA->capture_fft[8190-2*i+4*tune]=DATA->capture_fft[8190-2*i+2*tune+1]=0.0;
}
//span幅だけを計算する
tune(0Hzからの周波数同調点の幅)が、LPFの帯域幅より、大きい場合と、そうでない場合に分けたのは、
FFTの結果は、ご承知のように、周波数の不連続(跳躍)がある事と、それから
イメージ周波数を、消そうと(ゼロにする)、思ったからです。
こんな風です、果たして効果があるのか、どうか....(^_^;;
2.改良点
1.スピーカ出力をFFTして、下側の小窓で、見えるようにした。
これは、サウンドカードに出力したoutputを拾っているので、サウンドカード出力の音に、遅延を生じません。
2.画面にも、window関数の結果を、反映させた。
今までは、プログラミング上、時間的余裕がなかったので、window関数を掛けていませんでしたが、
今回は、画面のFFT結果も、window関数を掛けて、見やすくしました。
尚、画面のFFTは、入力2048ポイントに対して 4096ポイントFFTです。
3. 周波数移動を、マウスのクリックで、瞬時に移動できるように改良しました、楽です。
4.原因の解らないバグを、修正しました。
もしかしたら、これが原因で、M-AUDIOのDELTA44が動かなかったのでは.....現物がないので、確かめられん....
どんなバグかと、申しますと、
構造体のデータが、壊れるというものです。
struct
info
{
int func;
int usb;
int
carrier;
int band_width;
int slider_pos;
int
mode_pos;
int band_width_pos;
};
info mode_48KHz_usb= {1,1,1,2700,1,0,IDC_RADIO1USB,IDC_RADIO2BW2700};
info mode_96KHz_cwu= {1,1,1,2200,800,-7680,IDC_RADIO1CWU,IDC_RADIO2BW2200};
info mode_96KHz_usb= {1,1,1,2700,1,0,IDC_RADIO1USB,IDC_RADIO2BW2700};
mode_96KHz_lsb,mode_96KHz_usb};
原因不明ですが、info_arrayの、データが壊れるのです。
.............................................................................................................................................................................................................................................................
後で気づいたのですが、winMainの所で、こう宣言すれば、データは、壊れませんでした、何のこっちゃ
(-_-;;
info
info_array[6];
info_array[0]=mode_48KHz_lsb;
info_array[1]=mode_48KHz_usb;
info_array[2]=mode_96KHz_cwl;
info_array[3]=mode_96KHz_cwu;
info_array[4]=mode_96KHz_lsb;
info_array[5]=mode_96KHz_usb;
改善策は、
構造体の配列を止めて、構造体のアドレスの配列を、ヒープ領域に採りました。
理由は、
一旦、ヒープ領域を通す事で、データが壊れるのを防げるのでは、ないかなあーーと、思いましたもので.........根拠薄いなあ (^_^;;
info**
info_array;
info_array=new
info*[6*sizeof(info*)];
info_array[1]=&mode_48KHz_usb;
info_array[2]=&mode_96KHz_cwl;
info_array[3]=&mode_96KHz_cwu;
info_array[4]=&mode_96KHz_lsb;
info_array[5]=&mode_96KHz_usb;
慣れない、ポインタ配列を、使ったりして.....ええ勉強させてもろてます。
結果は、OK 、
「どんぴしゃ」とは、言わないまでも、データが、壊れなくなりましたです、 結果オーライ。( いつも、こればっかり、 根拠レス )
H.19.8.22