Jyaiko1.1でwave fileを再生する その2


黄色い線が、繰り返しのスタート地点。赤の線が、繰り返しの終了地点。

1.こんな使い方も... 

   
終点だけ指定する (赤い帯のあたりを、一回右クリック。 もう一回右クリックすると、指定解除)
    
    

    
始点だけ指定する(赤い帯のあたりを、一回左クリック。 もう一回左クリックすると、指定解除)

    

    
そして、'WAV read'ボタンを押して、wavefileの再生を、停止すると

    

    
サンプリング周波数が異なっていても、一瞬で、元の位置にもどります。
 

2.loopと、区間限定の繰り返しの再生

 
   前回では、wave fileを読み込んで、loopと区間限定の繰り返しの再生が、課題でした。

    なんとかできました。

    これを可能にしたのは、FILE *fpのランダムアクセス fseek関数です。

      #include <stdio.h>
      int fseek(FILE *fp, long offset, int origin);

    これで、ファイルのポインタを操れるのです。

    origin: ファイルの先頭位置に設定しました。 SEEK_SET

    ここで先ず、dataの先頭の位置を得るには、wavefileのヘッダーを読み込む。

wav_data.fp=read_wave_format_chunk(wave_filename,wav_data.loop_number,
      wav_data.rest_data_number,wave_samp);

    この時、現在のファイルポインタ位置は、データの先頭です。

wav_data.wave_data_start_pos=ftell(wav_data.fp);

   ftell関数で、現在の位置、つまり、dataの先頭を得て、wav_data.wave_data_start_posに、記憶しておきます。

   つまり、この部分は、format chunk。

   すると

    offset:   ファイルの先頭の位置からの、現在のデータの先頭位置は

           [dataの先頭からのoffset] + wav_data.wave_data_start_pos 。

    そして、[dataの先頭からのoffset] を、得るには 

    私のプログラムの場合、

    一回で、2048個*2 (L_channel + r_channel)の、float値を読み込む関数 void read_wave_data(FILE *fp,float *l_channel,float *r_channel)

    を使いました。

void read_wave_data(FILE *fp,float *l_channel,float *r_channel)
{
    int i=0;
    int j=0;
   for(i;i<4096;i++)
   {
     if(i%2)
     {
       fread(r_channel+j,sizeof(float),1,fp);
       j++; 
     }
    else
     {
       fread(l_channel+j,sizeof(float),1,fp);
     }
   }

}

    ですので

    この関数read_wave_dataを、一回実行すると

      4096回 * 4bytes = 16384 bytes

        進みますので、

    ファイルの先頭の位置からのofffsetも、

      16348bytes + furmat chunk (私の場合 44bytesになった)

    で、得られる事になります。

    void read_wave_data関数を、何回実行すれば、全データを読み込めるかの、ループ回数は

wav_data.fp=read_wave_format_chunk(wave_filename,wav_data.loop_number,
      wav_data.rest_data_number,wave_samp);

    この関数のwav_data.loop_numberに、収納されています。

    この関数は、一回の実行で、FILE *fpのポインタアドレス、ループ回数 loop_number、そして

    残りのfloat値のデータの個数 rest_data_number、及び、このファイルのサンプリング周波数 sampの、 4つ変数の値を、いっぺんで返してくれます。

    これには、変数の参照を使いました。

   この関数の宣言は、以下のようになってます。

FILE* read_wave_format_chunk(wchar_t* filename,DWORD& loop_number,DWORD& rest_data_number,int& samp  );

   参照って、便利ですねえ、知らんかったわ (^_^;;

   そんなわけで、k回 void read_wave_data関数を実行すれば

   wavefileの先頭からのoffset値は

      k回 * 16348bytes + format chunk(私の場合 44bytesになった)

   に、なります。

   以上が、今回のプログラムの骨格です。

   時々、ずっこけるけんど、ちょっとだけ便利でっしゃろ (^_^)

 H.20.5.23