RedHawk Realtime LinuxCUDA による高解像度連続周波数解析デモプログラム

 

以下の画面は、Spectrum社の高速ADを入力とするGPU-VSIPLで作成した連続周波数解析プログラムの画面です。(モーションGIFに変換しています)

 ADの入力は14bit/50MHzで連続収録を行い、全てのデータに対して1MポイントのFFTを行い、周波数の全点ピークサーチを行っています。

方形波のスイープを入力信号としていますので、最大値の定数倍にスプリアスが現れ、折り返し周波数が現れているのをみることが出来ます。

 

CPU: Dell T5400 Xeon 2 Core/2 CPU 2.8GHz/2GByte Memory

OS: RedHawk 5.4 RealTime Linux

AD Card: Spectrum M2i.4031

CUDA GPU:NVIDIA Quadro FX3700/512MByte Memory

Sampling rate  : 50.0 M Sample/sec

Frequency Band: 25.0 MHz

FFT Length: 1048576 Points

Hz/Bin: 47.6837 Hz

CycleTime: 25.3 msec.

Window: Blackman

Display Rate: 20.97ms

  

 
 
 
 
 

AD入力処理および表示処理を除いたVSIPLの主要なプログラム

 
                sp = (signed short int *)buffer;
                Length = 1024 * 1024;
                HarfSize = Length/2;
               for(i=0;i<Length;i++)
               {
                       ad[i]=(signed int)*sp++;              /* Convert short to int */
               }
               vsip_blockadmit_i(blk_i, VSIP_TRUE);          /* Admit blk_i after populating input user data array */
               vsip_blockadmit_f(blk_o, VSIP_FALSE);         /* Admit blk_o after populating input user data array */
               vsip_vcopy_i_f(vec_i,rx_raw);
               vsip_svmul_f (full_scale,rx_raw,rx);          /* Scale A/D values by full-scale */
               vsip_vmul_f (vec_w,rx_raw,rx_w);              /* Apply Blackman window to input signal */
               vsip_rcfftop_f(fft_obj,rx_w,Rx);              /* Compute FFT of windowed input signal */
               vsip_cvmag_f (Rx, vec_o);                     /* Compute magnitude of FFT to get spectral estimate */
               vsip_blockrelease_i(blk_i, VSIP_FALSE);       /* Admit blk_i after populating input user data array */
               vsip_blockrelease_f(blk_o, VSIP_TRUE);        /* Admit blk_o after populating input user data array */
               peak_max_i=0;peak_max=0.0;
               for(i=1;i<HarfSize;i++)
               {
                       if ((out[i-1]<out[i])&&(out[i]>out[i+1])) //山の条件
                       {
                               if (out[i]>peak_max)
                               {
                                      peak_max_i =i;
                                      peak_max=update_max(i,out[i]); // 最大値を登録
                               }
                       }
               }