DirectX EmptyProjectを使う その4


7MHz cw帯を拡大  Soft66DB2使用 7030KHz位まで表示

 1. 出力特性を見る
      上図は、7MHzのcw bandを、拡大したものです。

      拡大とは、1024点 FFTなら、そのFFT出力を、画面に収まるように、縮小しないで、表示した場合です。

      あれれっ! CWで、きれいな波形と、そうでもないものが、見られますね。

      ご心配なく、これは、恐らく、私のソフトの為だと、思います。

      私の持っているSGでは、きれいな波形が表示されるのは、皆無でしたから、多分そのせいです......


      さて、設計通りのfilterが、できているか?  出力を観察致しました。

      入力は、ノイズのみで測っています。CW時は、offsetを1KHzに、採っています。

 

 

CW時( 1KHzが中心  96KHz sanpling )




      うーむ、80Hzは、嘘かもしれませんね... 切れ悪いし......他は、なんとか...

      なんせ、down sampling してないもので....

     最後に、強入力があった時の出力です。

              

 2.大分安定して来ました

     このプログラムを単独で動かしていても、 何かのきっかけで、すぐ、sound出力が、潰れてしまいました。

     これの解決策は、何と!

     C言語で定義していた構造体を、C++での構造体に変える事、でした。

     ご承知のように、PortAudioの、test プログラムは、C言語で書かれています。

typedef  struct
{
 double* my_data_Q;
 double* my_data_I;
 double  current_Q;
 double  current_I;
 SAMPLE* output;
 double  RF_gain;

}
paTestData;

これの定義を

struct  paTestData
{
 double* my_data_Q;
 double* my_data_I;
 double  current_Q;
 double  current_I;
 float* output;

};

     と、書き換えただけで、安定してきました。

     このプログラムを、単体で動かしているかぎり、大分安定してきました。

     正直な話、私は、構造体を使わねばならん程、大きなプログラムを書くのは、皆無です、慣れてない。

     C言語でさえ、解らない時は、教科書を覗いているのですから。

     C++言語の構造体は、クラスと、殆ど、変わらないそうです、何せ、costructorも、持てるらしい....C++ 構造体 参照。


     しかしですね。

     このプログラムを走らせている時に、Internet Explorerを立ち上げたり、他のプログラムを走らせると、頻繁に、こけるのです.....

     Rockyや、PowerSDRでは、絶対に、そうならないのです。

     タスクマネージャーを見ていると、他のプログラムを立ち上げる時、一時的に、CPUの負荷が90%位になるのです。

     これが、

     このプログラムが、こける、原因だと思いますわ....

     

 3.発想の転換が必要やっ!

    私のプログラムは、PortAudioのCallback関数内で、soundの出力まで、全て処理しています。

    これが、CPUに対して、高負荷に為るのだと思います。

static int pa_test_Callback(const void *inputBuffer,void *outputBuffer,
         unsigned long framesPerBuffer,
         const PaStreamCallbackTimeInfo* timeInfo,
         PaStreamCallbackFlags statusFlags,
         void *userData)
{
   paTestData *data = (paTestData*)userData;
   float *out = (float*)outputBuffer;
   float  *in  = (float*)inputBuffer;
 
       if( inputBuffer == NULL )
    {
     for( i=0; i<Capture_Data_Length; i++ )
     {
      *out++ = SAMPLE_SILENCE; 
     }
    }
    else
    {
     if(image_reject_test)
     {
     for( i = 0 ;i < Capture_Data_Length;i++ )
      {
       //ここで、複素周波数遷移して、0Hzに移す
     
       data->current_Q=gain_left* *in++;
       data->current_I=RF_gain* *in++;//right

       scope_fft_Q[i]=data->current_Q*cos(pi*i+phase_left) - data->current_I*sin(pi*i+phase_left);
       scope_fft_I[i]=data->current_Q*scope_fft_multify_sin [i] + data->current_I*scope_fft_multify_cos[i];

      }
    
}
     else
     {
      //int sampling_base=1024*2;

      for( i = 0 ;i < Capture_Data_Length;i++ )
      {
       //ここで、複素周波数遷移して、0Hzに移す
     
       data->current_Q=gain_left* *in++;//left
       data->current_I=RF_gain* *in++;//right


      /* data->my_data_Q[i+ Capture_Data_Length*circular_count ] =
        data->current_Q*cos(two_pai*tune*i/sampling_base) - data->current_I*sin(two_pai*tune*i/sampling_base);

       data->my_data_I[i+Capture_Data_Length*circular_count] =
        data->current_Q*sin(two_pai*tune*i/sampling_base) + data->current_I*cos(two_pai*tune*i/sampling_base);
       */
       data->my_data_Q[i+ Capture_Data_Length*circular_count ] =
        data->current_Q*cos(keisuu*tune*i) - data->current_I*sin(keisuu*tune*i);

         data->my_data_I[i+Capture_Data_Length*circular_count] =
         data->current_Q*sin(keisuu*tune*i) + data->current_I*cos(keisuu*tune*i);

        scope_fft_Q[i]=data->current_Q*scope_fft_multify_cos[i] - data->current_I*scope_fft_multify_sin[i];
        scope_fft_I[i]=data->current_Q*scope_fft_multify_sin [i] + data->current_I*scope_fft_multify_cos[i];


     }
        myfir->get_CaptureData_FFT_result(data->my_data_Q+Capture_Data_Length*(circular_count-1),
                  data->my_data_I+Capture_Data_Length*(circular_count-1),
                  Capture_Data_Length*2,capture_fft,work,ip,w);

   
     }
        myfir->multi_FFT_results(capture_fft,coef_fft,result);
       myfir->get_data_from_mulit_FFT_results(result,Capture_Data_Length,
               data->output,USB,ip,w);

       peak_output=0.0f;
       //ここで、AGCを掛ける
       if(AGC)
       {
       //peak detect
       for(i=0;i<Capture_Data_Length;i++)
       {
        peak_output=(float)max(peak_output,data->output[i]);
       }

       //gain=exp(0.64f-peak_output/1.4f);//0.64=noise even AGC
      gain=exp(0.5f-peak_output/1.4f);//0.64=noise even AGC
     //gain=exp(-peak_output/3.5f);//0.64=noise even AGC
   
      for(i=0;i<Capture_Data_Length;i++)
      {
        *out++=data->output[i]*gain;
        *out++=-(data->output[i]*gain);

      }

    }
     else
       for(i=0;i<Capture_Data_Length;i++)
          *out++=*out++=data->output[i];
  
    circular_count++;
    if(circular_count== Buffer_Multi)
    circular_count=1;
 
  }

 return paContinue;
}


    して、発想の転換とは?

    PortAudioの Callback関数内で、全て処理するのでは無くて、

    Callback関数は、外部入力を受け付けるだけで、そのまま出力し、

    他の場所で、処理する事が、必要と考えます。

    それは、何なのか?と、申しますと、

    よく解ってないのですが、DirectShow なるものでは、ないかと....

 4.DirectShow って、何や!

 

      GraphEditなるものを使って、avi ファイルが、再生されています。

 

      何か? まだ、よく解らんのですが....よさげ ちゃいますか?
 
    H.19.6.27