Jyaiko1.1を使ってwave file
に書き込む 2.ほんじゃ、どうする? //48KHz、96KHz samplingに共通の設定
whd.chunk_ID =0x46464952;//"RIFF" if( (err=_wfopen_s(&fp2, filename,L"wb"))
!=0) if(!fwrite(&whd.file_size,sizeof(DWORD),1,fp2)) if(!fwrite(&whd.fmt_ID,sizeof(DWORD),1,fp2))//fmt if(!fwrite(&whd.fmt_size,sizeof(DWORD),1,fp2))//fmt
size=16 if(!fwrite(&whd.data_ID,sizeof(DWORD),1,fp2))//data return
fp2; } if(wav_write_data.isWaveWriteOn) if(wav_write_data.fp
!=NULL) } close_file(wav_write_data.fp);
1.DirectShowを使った録音の調子が、悪い
どうも、調子がよくありません....
音声は、正確に再生されるのですが、帯域が狭くなってしまいます.....
DirectShowの使用を、諦めましょう、涙 (-_-)
前節で、fread関数を使いました。
fread関数をfwrite関数に書き換えると、殆ど同じプログラムが使えます。
write_wave_format_chunk関数を、以下のように作ります。
所で、fmt
size=16 に指定すると、PowerSDRでも、再生できるようになります。
FILE*
write_wave_format_chunk(wchar_t* filename,bool
is_sampling_high )
{
FILE *fp2;
WAVE_HDR
whd;
whd.wfm.cbSize=0;
whd.wfm.wFormatTag=3;
whd.wfm.nChannels=2;
whd.wfm.nBlockAlign=8;
whd.wfm.wBitsPerSample=32;
whd.fmt_size=16;
whd.file_type=0x45564157;//"WAVE"
whd.fmt_ID =0x20746d66;//"fmt"
whd.fmt_size=16;
whd.data_ID
=0x61746164;//"data"
whd.data_size=0;
whd.file_size=0;
if(is_sampling_high)
{
whd.wfm.nSamplesPerSec=96000;
whd.wfm.nAvgBytesPerSec=768000;
}
else
{
whd.wfm.nSamplesPerSec=48000;
whd.wfm.nAvgBytesPerSec=384000;
}
errno_t
err;
return
NULL;
if(!fwrite(&whd.chunk_ID,sizeof(DWORD),1,fp2))//RIFF
return
NULL;
return
NULL;
if(!fwrite(&whd.file_type,sizeof(DWORD),1,fp2))//WAVE
return
NULL;
return
NULL;
return NULL;
//fmt
size=16
if(!fwrite(&whd.wfm.wFormatTag,sizeof(WORD),1,fp2))
return
NULL;
if(!fwrite(&whd.wfm.nChannels,sizeof(WORD),1,fp2))
return
NULL;
if(!fwrite(&whd.wfm.nSamplesPerSec,sizeof(DWORD),1,fp2))
return
NULL;
if(!fwrite(&whd.wfm.nAvgBytesPerSec,sizeof(DWORD),1,fp2))
return
NULL;
if(!fwrite(&whd.wfm.nBlockAlign,sizeof(WORD),1,fp2))
return
NULL;
if(!fwrite(&whd.wfm.wBitsPerSample,sizeof(WORD),1,fp2))
return
NULL;
return
NULL;
//data
size
if(!fwrite(&whd.data_size,sizeof(DWORD),1,fp2))
return
NULL;
}
で、write_wave_data関数も、以下のように作っておきます。
void write_wave_data(FILE
*fp,float *l_channel,float *r_channel)
{
int i=0;
int
j=0;
for(i;i<4096;i++)
{
if(i%2)
{
fwrite(r_channel+j,sizeof(float),1,fp);
j++;
}
else
{
fwrite(l_channel+j,sizeof(float),1,fp);
}
}
ほとんど,前節の
read_wave_data関数が使えます。
ほんで、Rec ボタンを押すと、
IDC_BUTTON_WAVE_WRITE イベントが発生します。
case IDC_BUTTON_WAVE_WRITE:
{
if(wav_read_data.isWaveReadOn) // 再生している時は、録音しない。
break;
wav_write_data.isWaveWriteOn=!wav_write_data.isWaveWriteOn; //bool isWaveWriteOnと bool isWaveWriteStartedを使うのはタイミングの問題回避のため
{
g_ControlDlg.GetButton(IDC_BUTTON_WAVE_WRITE)->GetElement(1)->TextureColor.States[
DXUT_STATE_NORMAL ]
=g_ControlDlg.GetButton(IDC_BUTTON_WAVE_WRITE)->GetElement(1)->TextureColor.States[
DXUT_STATE_MOUSEOVER ]
=D3DCOLOR_ARGB(255,255,0,0);
wave_filename=L"temp.wav"; //ファイルネームは、今の所、決め打ち
wav_write_data.loop_number=0;
wav_write_data.fp=write_wave_format_chunk(wave_filename,sampling_high);
{
wav_write_data.wave_data_start_pos=ftell(wav_write_data.fp); //write_wave_format_chunk関数を実行したので、今のファイルポインタは、dataの先頭
wav_write_data.k=0;
::ResumeThread(g_wave_write_thread); //書き込みスレッド開始
wav_write_data.isWaveWriteStarted=true;
wav_write_data.total_sec=0; //録音開始秒=0
g_ControlDlg.GetStatic(IDC_STATIC_SHOW_TIME)->SetVisible(true); //録音時間表示
}
そんで、録音終了の時に、ファイルサイズ、dataサイズを、format
chunkの所定位置に、書き込みます。
ファイルをcloseするまでは、ここでも、fseek関数
が使えて、便利です。
wav_write_data.k_stop_number=ftell(wav_write_data.fp); //終了ボタンを押した時の、ファイルポインタの位置= ファイルサイズ
DWORD
data_size[2]={0,0};
data_size[0]=wav_write_data.k_stop_number-4; //file size
-4("RIFF")
data_size[1]=wav_write_data.k_stop_number-44;//file
size-44(chunk size)
//write file
size
fseek(wav_write_data.fp,4,SEEK_SET);//after
"RIFF"
fwrite(&data_size[0],4,1,wav_write_data.fp);
fseek(wav_write_data.fp,40,SEEK_SET);//after
"data"
fwrite(&data_size[1],4,1,wav_write_data.fp);
wav_read_data.k_start_number=0;
wav_read_data.isStartPos_Set=false;
wav_read_data.k_stop_number=wav_read_data.k;
wav_read_data.isStopPos_Set=false;
今の所、ファイルネームは、固定で、メモ録音みたいに使っています。
結局、DirectShowを使い切れませんでしたね....ちょっと、くやしい。
DirectShowの解説本、でないかな......(かの有名な本は、MSDNの、解説の域を出ないそうな...)
最後に、Jyaiko1.1 で、録音した IQ wave
ファイルを添付いたします。(7MHz帯) [ PowerSDR等で、再生してもらわないと、何も聞こえません。]
96KHz IEEE_FLOAT32bits
example
48KHz IEEE_FLOAT32bits example
使用しているアンテナは、広帯域のものですので、感度は、よくありません。
format
は、 IEEE_FLOAT 32ビット、96KHz and 48KHzサンプリングですので、注意
Jyaiko1.1では、入力段で録音しているだけですので、 結果として
使用している Soft66DB2の優秀さを表すものだと思います。
H.20.6.1