EmptyProjectを使う その5(スレッドの優先度等) やっと、WaitForSingleObjectを使う方法を、理解できました。 for( i = 0 ;i <
Capture_Data_Length;i++ ) } //output } DWORD WINAPI myThread(LPVOID x) paTestData* DATA=(paTestData*)x; EnterCriticalSection(§ion); limit=Capture_Data_Length*DATA->circular; for(i=0;i<2048;i++) DATA->my_data_I[i+limit]
= scope_fft_Q[i]=DATA->current_Q[i]*scope_fft_multify_cos[i]
-
DATA->current_I[i]*scope_fft_multify_sin[i]; DATA->myfir->multi_FFT_results(DATA->capture_fft,DATA->coef_fft,DATA->result); //peak
detect
DATA->gain=exp(0.5f-DATA->peak_output/1.4f); ::Reset_Event(thread_event); return 0; } ::SetThreadPriority(g_thread,THREAD_PRIORITY_TIME_CRITICAL
);//THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_ABOVE_NORMAL thread_event=::CreateEvent(0,true,false,NULL);
//manualreset set_scale();
0.追加記事 WaitForSingleObjectを、使う
Pa_CallBack関数の所で、計算スレッドを作動させるには、
else
{
{
//入力を受け付けるのみ
data->current_Q[i]=gain_left* *in++;//left
data->current_I[i]=RF_gain*
*in++;//right
//計算の、スレッド開始
::SetEvent(thread_event);
//manualReset
for(i=0;i<Capture_Data_Length;i++)
{
*out++=data->output[i]*data->gain;
*out++=-(data->output[i]*data->gain);
// *out++=data->output[i]*gain;
と、します。
一方、 計算させるスレッドでは、
//*******
thread ***********************************************
{
int
i=0;
while(1)
{
::WaitForSingleObject(thread_event,INFINITE);
{
DATA->my_data_Q[i+
limit ]
=
DATA->current_Q[i]*cos(keisuu*tune*i)
- DATA->current_I[i]*sin(keisuu*tune*i);
DATA->current_Q[i]*sin(keisuu*tune*i)
+ DATA->current_I[i]*cos(keisuu*tune*i);
scope_fft_I[i]=DATA->current_Q[i]*scope_fft_multify_sin
[i] +
DATA->current_I[i]*scope_fft_multify_cos[i];
}
DATA->myfir->get_CaptureData_FFT_result(DATA->my_data_Q+Capture_Data_Length*(DATA->circular-1),
DATA->my_data_I+Capture_Data_Length*(DATA->circular-1),
4096,DATA->capture_fft, work,ip,w);
DATA->myfir->get_data_from_mulit_FFT_results(DATA->result,2048,
DATA->output,0,ip,w);
if(AGC)
{
DATA->peak_output=0.0f;
for(i=0;i<2048;i++)
{
DATA->peak_output=(float)max(DATA->peak_output,DATA->output[i]);
}
else
DATA->gain=1.0f;
DATA->circular++;
if(DATA->circular==
Buffer_Multi)
DATA->circular=
1;
LeaveCriticalSection(§ion);
}
今回は、プログラムが、固まるのを防止するための ::Sleep(1) が、不要ですね、ええ調子 ♪
なお、Eventを作る時、WinMain関数内で、このeventを、手動リセットに、設定しておきます。
//****
thread **************************************************
g_thread=::CreateThread(NULL,0,myThread,&data_origin,CREATE_SUSPENDED,&d);
//THREAD_PRIORITY_TIME_CRITICAL
InitializeCriticalSection(§ion);
InitDlg();
selected_mode=2;
これで、かなり、安定しました、サンキュー (*^_^*)
追加記事、終わり。
1.スレッド 及び、プロセスの優先度 |
タスクマネージャーで、選択したプログラムの優先度を、変えられるのを、知りませんでした。 Rockyの優先度は、リアルタイムに、初期設定されている。 PowerSDRの優先度は、通常に、初期設定されています。 |
何故か? |
自分のプログラムを、いじって診て、初めて、解りました。 PortAudio、DirectX等を使う、自作のプログラムで、プロセスの優先度を上げると、うまく動作しませんでした.... 前節で、私は、ぼやいておりました 「 PortAudioの Callback関数内で、全て処理するのでは無くて、 Callback関数は、外部入力を受け付けるだけで、そのまま出力し、 他の場所で、処理する事が、必要と考えます。 それは、何なのか?と、申しますと、 よく解ってないのですが、DirectShow なるものでは、ないかと....」 とにかく、他のプログラムを起動した時に、 自作のプログラムで、音声が歪んでしまうのが、いやでした。我慢なりませんわ。 WinMainの最初に // TODO: Perform any application-level initialization here //このprocessの、優先度を設定する----------------------------------------- //::SetPriorityClass(::GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS); これは、不発。 |
2.DirectShowを使うまでも無い ::SetThreadPriority(g_thread,THREAD_PRIORITY_TIME_CRITICAL
); //THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_ABOVE_NORMAL DWORD WINAPI myThread(LPVOID
x) EnterCriticalSection(§ion); limit=Capture_Data_Length*DATA->circular;
for(i=0;i<2048;i++)
DATA->my_data_I[i+limit]
=
scope_fft_Q[i]=DATA->current_Q[i]*scope_fft_multify_cos[i] -
DATA->current_I[i]*scope_fft_multify_sin[i];
DATA->myfir->multi_FFT_results(DATA->capture_fft,DATA->coef_fft,DATA->result);
//peakdetect<
br>
for(i=0;i<2048;i++)<br> DATA->peak_output=(float)max(DATA->peak_output,DATA->output[i]);<br> <br> DATA->gain=exp(0.5f-DATA->peak_output/1.4f);//0.64=noise
even AGC
LeaveCriticalSection(§ion); DATA->can_fft=0; return
0; |
H.19.7.3 |