EmptyProjectを使う その10 (FFTで周波数shift)


下の小窓は、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]=DATA->capture_fft[8192-2*tune+2*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];

    }  

    for(i=0;i<tune;i++)
    {
     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;
   }

  }

 

next_stage:

//DATA->capture_fft[2*i]
  //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 offset;
 int slider_pos;
 int mode_pos;
 int band_width_pos;
};

info mode_48KHz_lsb= {1,0,1,2700,1,0,IDC_RADIO1LSB,IDC_RADIO2BW2700};
info mode_48KHz_usb= {1,1,1,2700,1,0,IDC_RADIO1USB,IDC_RADIO2BW2700};

info mode_96KHz_cwl= {1,0,1,2200,800,-7680,IDC_RADIO1CWL,IDC_RADIO2BW2200};
info mode_96KHz_cwu= {1,1,1,2200,800,-7680,IDC_RADIO1CWU,IDC_RADIO2BW2200};

info mode_96KHz_lsb= {1,0,1,2700,1,0,IDC_RADIO1LSB,IDC_RADIO2BW2700};
info mode_96KHz_usb= {1,1,1,2700,1,0,IDC_RADIO1USB,IDC_RADIO2BW2700};

info info_array[6]={mode_48KHz_lsb,mode_48KHz_usb,mode_96KHz_cwl,mode_96KHz_cwu,
     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[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;
      
      慣れない、ポインタ配列を、使ったりして.....ええ勉強させてもろてます。

      結果は、OK 、

      「どんぴしゃ」とは、言わないまでも、データが、壊れなくなりましたです、 結果オーライ。( いつも、こればっかり、 根拠レス )

   H.19.8.22