//au2802プロジェクト
// グラフィック描画のためにlist0808.cppを使用する
// C/C++の設定をマルチスレッドに変更
#include <Windows.h>
#include <vfw.h>
// Video for Windows include file
// 併せてvfw32.libの追加が必要
// PlaySoundのためwinmm.libの追加が必要
#include <stdio.h>
#include <conio.h> // getch()の宣言
#include <math.h> // fabs();
#include "list0808.h"
void f_avi( char * );
////////
void main()
{
char * pfn;
pfn = file_open( );
f_avi( pfn );
printf("quit?");
getch();
gr_quit();
return ;
}
void f_avi( char * pfn )
{
int i, j, jj, k;
PAVIFILE paviin;
AVIFILEINFO pfi;
AVISTREAMINFO si[2];
PAVISTREAM pvs[2];
HRESULT rc;
PGETFRAME pvf;
LPBITMAPINFOHEADER pbmpih;
char cbuf[100];
int nsw = 0; //av28
int ssw = 0;
int msw = 0;
int au;
int vi;
double * a0;
double * v0;
double * v1; // av_1 diff
double as,vs,vs1;
short int * ap;
rc = AVIFileOpen( &paviin, pfn, OF_READ, NULL);
if( rc ) { printf( "open err\n" );
return;
}
pfi.dwStreams = 0;
AVIFileInfo(paviin, &pfi, sizeof(AVIFILEINFO));
printf( "strs = %d \n", pfi.dwStreams);
for( i = 0; i < pfi.dwStreams; i++ ){
AVIFileGetStream( paviin, &(pvs[i]), 0, i );
AVIStreamAddRef(pvs[i]); // ストリームの参照カウントを1増やす
AVIStreamInfo( pvs[i], &(si[i]), sizeof(AVISTREAMINFO) );
if( si[i].fccType == streamtypeVIDEO )
vi = i;
if( si[i].fccType == streamtypeAUDIO )
au = i;
}
pvf = AVIStreamGetFrameOpen( pvs[vi],
(LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);
// 解凍の準備
printf("vi_S=%d vi_R=%d vi_length=%d \n",
si[vi].dwScale, si[vi].dwRate, si[vi].dwLength);
int nfh = si[vi].rcFrame.bottom - si[vi].rcFrame.top;
int nfw = si[vi].rcFrame.right - si[vi].rcFrame.left;
printf( "h = %d w = %d\n", nfh , nfw);
printf( "au_S=%d au_R=%d au_length=%d %d(frame)\n",
si[au].dwScale, si[au].dwRate, si[au].dwLength, si[au].dwLength/1067);
printf("non_monitor - nキー , 表示 - s以外のキー ?");
if(getch() == 'n')
nsw = 1;
if( nsw == 0 ){
printf("\nコマ送り - sキー , 連続表示 - s以外のキー ?");
if(getch() == 's')
ssw = 1;
printf("\n白黒 - mキー , カラー - m以外のキー ?");
if(getch() == 'm')
msw = 1;
}
a0 = (double *) malloc( si[vi].dwLength * sizeof(double));
v0 = (double *) malloc( si[vi].dwLength * sizeof(double));
v1 = (double *) malloc( si[vi].dwLength * sizeof(double));
// 以下の関数はlist0808.cppで定義されている
gr_init( nfw, nfh ); // グラフィックウィンドウを生成
gr_clr(); // 仮想画面クリア
gr_draw(); // 仮想画面をグラフィックウィンドウにコピー
gr_active();
int cnt = 0x40 + nfw * nfh *3 +100;
printf("cnt = %d\n",cnt);
BYTE * bmp0;
BYTE * bmp1;
bmp0 = (BYTE *)malloc( cnt );
bmp1 = (BYTE *)malloc( cnt );
int nn,m,km;
long ab,ab2;
BYTE * pbuf;
PCMWAVEFORMAT pwf;
BYTE *fp;
int n ;
char fname[100];
int ns = 1067 * 2; // 1/29.97秒
pbuf = (BYTE *)malloc( ns + 1000); // 1/29.97秒 * 32kHz
pwf.wf.wFormatTag = WAVE_FORMAT_PCM;
//MMREG.H(1394):#define WAVE_FORMAT_PCM 1
//MMSYSTEM.H(703):#define WAVE_FORMAT_PCM 1
pwf.wf.nChannels = 1;
pwf.wf.nSamplesPerSec = 32000;
pwf.wf.nAvgBytesPerSec = 64000;
pwf.wf.nBlockAlign = 2;
pwf.wBitsPerSample = 16;
BYTE * pp;
// 1フレーム毎切り出しのループ
for( jj = 0; jj< si[vi].dwLength; jj++){
// ビデオストリームから1フレーム切り出す
// 0フレームが最初のフレーム
pbmpih = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pvf,jj);
int cnt = (pbmpih -> biSize) + (pbmpih->biSizeImage);
// printf( "j= %d pbmp = %d bmpih.h = %d size =%d all = %d\n",
// jj,pbmpih -> biSize , pbmpih->biBitCount ,
// pbmpih->biSizeImage, cnt);
// 描画ウィンドウへ描画のための準備、list0808.cppの関数
// ppにbmpのデータ部分の先頭が渡される
pp = gr_set_bmph( pbmpih );
vs = 0;
vs1 = 0;
for(k = 0;k < nfh ;k++){
for(m =0;m< nfw ;m++){
km = (k * nfw + m ) * 3;
if( msw ){
nn =( pp[km ]
+ pp[km +1]
+ pp[km +2] )/3;
bmp0[km ]= bmp0[km +1]
= bmp0[km +2] = nn;
}
else{
bmp0[km ] = pp[km ];
bmp0[km +1] = pp[km +1] ;
bmp0[km +2] = pp[km +2] ;
}
// av :画面平均輝度の計算
vs = vs + pp[km ] + pp[km +1] + pp[km +2] ;
// av_1 :平均変化量の計算
vs1 = vs1 + fabs( bmp0[km ] - bmp1[km ] )
+ fabs( bmp0[km +1] - bmp1[km +1])
+ fabs( bmp0[km +2] - bmp1[km +2]);
bmp1[km ] = bmp0[km ];
bmp1[km +1] = bmp0[km +1];
bmp1[km +2] = bmp0[km +2];
}
}
// 画素数で割る
v0[jj]=vs / (640.0 * 480.0 * 3); // av
v1[jj]=vs1 / (640.0 * 480.0 * 3); // av_1
wsprintf(cbuf,"[%s] frame %d/%d ",pfn, jj, si[vi].dwLength);
gr_caption( cbuf );
if( nsw == 0){
gr_bmp( bmp0);
gr_draw();
}
if( ssw ){
int r;
r = MessageBox(NULL,
"次のフレーム-はい 前のフレーム-いいえ 連続表示-キャンセル",
"...",
MB_YESNOCANCEL);
if( r == IDNO )
jj=jj-2;
if( r == IDCANCEL )
ssw = 0;
}
// オーディオの処理
wsprintf( cbuf,"RIFF");
fp = pbuf;
fp = swrite( (BYTE *)cbuf, 4, fp);
n = 20 + 16 + 8 + ns;
fp = swrite( (BYTE *)(&n), 4, fp);
wsprintf(cbuf,"WAVEfmt ");
fp = swrite( (BYTE *)cbuf, 8, fp);
n = 16;
fp = swrite( (BYTE *)(&n), 4, fp);
fp = swrite( (BYTE *)(&pwf), 16, fp);
wsprintf(cbuf,"data");
fp = swrite( (BYTE *)cbuf, 4,fp);
fp = swrite( (BYTE *)(&ns), 4, fp);
// オーディオのストリームを1フレーム(nsサンプル)分読み出す
AVIStreamRead( pvs[au], jj * ns/2, ns, fp, ns, &ab, &ab2);
if( nsw == 0){ // av28
PlaySound( (char *)pbuf, NULL,
SND_MEMORY | SND_SYNC);
}
// 1フレーム分平均の音の大きさを計算
ap = (short int *)fp;
as = 0;
for(j = 0;j < ns/2; j++){
as = as + fabs( (double)ap[j] );
}
a0[jj]= as / (double)(ns/2);
printf("frame= %4d v0= %7.3f v1= %7.3f a0= %7.1f\n",
jj, v0[jj], v1[jj], a0[jj]);
}
AVIStreamGetFrameClose(pvf);
AVIStreamRelease( pvs[0]);
AVIStreamRelease( pvs[1]);
AVIFileRelease( paviin );
// csv形式で計算結果をファイルに保存
char ccbuf[100];
char cb2[100];
i =0;
while( pfn[i] != '.'){
ccbuf[i] = pfn[i];
i++;
}
ccbuf[i]=0;
sprintf(cb2,"%s_2.csv",ccbuf);
FILE *fp2;
fp2 = fopen(cb2,"w");
for(i = 0;i< si[vi].dwLength;i++)
fprintf(fp2, "%f,%f,%f \n", v0[i], v1[i], a0[i] );
fclose(fp2 );
}