VC++でデジタルフィルタ
Posted: 2013年1月11日(金) 14:02
VC++2008proでデジタルフィルタを作成しています。
GetFrq関数で生成した音にエフェクトをかけて再生することはできたのですが、
fopenを使用してバイナリファイルにエフェクトをかけることができません。
ファイルオープンの方法に問題があると思うのですが特定できません。
問題個所分かる人がいればお願いします。
GetFrq関数で生成した音にエフェクトをかけて再生することはできたのですが、
fopenを使用してバイナリファイルにエフェクトをかけることができません。
ファイルオープンの方法に問題があると思うのですが特定できません。
問題個所分かる人がいればお願いします。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <afx.h>
#pragma comment(linker,"/subsystem:windows")
#pragma comment(linker,"/NODEFAULTLIB")
#pragma comment(lib,"winmm.lib")//winmm.libをリンクする
#ifdef __cplusplus
extern "C" {
#endif
int _fltused=1;
void _cdecl _check_commonlanguageruntime_version(){}
int __cdecl _ftol2_sse() {
int integral;
short oldfcw, newfcw;
__asm {
fstcw [oldfcw]
mov ax,[oldfcw]
or ax,0c00h ; chop
mov [newfcw],ax
fldcw [newfcw]
fistp dword ptr[integral]
fldcw [oldfcw]
}
return integral;
}
int __cdecl _ftol2() {return _ftol2_sse();}
#ifdef __cplusplus
}
#endif
/*
float GetFrq(char c)
{
switch(c){
case 'a': return 440*0.5946f;//ド 440*2^( 3/12)
case 's': return 440*0.6674f;//レ 440*2^( 5/12)
case 'd': return 440*0.7492f;//ミ 440*2^( 7/12)
case 'f': return 440*0.8409f;//ファ440*2^( 8/12)
case 'g': return 440*0.8909f;//ソ 440*2^(10/12)
case 'h': return 440*1.0f; //ラ 440*2^(12/12)
case 'j': return 440*1.1225f;//シ 440*2^(12/12)
case 'k': return 440*1.1892f;//ド 440*2^(15/12)
case 'a2': return 440*0.5946f;//ド 440*2^( 3/12)
case 's2': return 440*0.6674f;//レ 440*2^( 5/12)
case 'd2': return 440*0.7492f;//ミ 440*2^( 7/12)
case 'f2': return 440*0.8409f;//ファ440*2^( 8/12)
case 'g2': return 440*0.8909f;//ソ 440*2^(10/12)
case 'h2': return 440*1.0f; //ラ 440*2^(12/12)
case 'j2': return 440*1.1225f;//シ 440*2^(12/12)
case 'k2': return 440*1.1892f;//ド 440*2^(15/12)
}
return 0;
}
*/
void WinMainCRTStartup()
{
// char* music = "asdfghjka2s2d2f2g2h2j2k2";//楽譜データ(ここを変えると、なる音が変わります)
// int = fp;
FILE *fp;
char music[1000];
long t, n = 0;
// const char filename[] = "TITLE 003.wav";
// const char mode[] = "wb";
float pm = 0.5f;//1つあたりの音符の時間(秒)
if((fp = fopen("\\FILE\\Redirect$\\Student\\523\\52329\\Desktop\\TITLE 003.wav", "wb")) == NULL)
{
printf("ファイルの書込みに失敗しました.\n");
exit(1);
}
else
{
fp = fopen("\\FILE\\Redirect$\\Student\\523\\52329\\Desktop\\TITLE 003.wav", "wb");
}
fscanf(fp, "%f", &(music[n]));
/*
//波形生成
long musictime = (long)(lstrlen(music)*44100);//1[sec] = 44100[sample] サンプリングレート44.1kHz
short* wave_data=(short*)GlobalAlloc(GPTR,sizeof(short)*musictime);
long ptime = (long)(44100*pm);
*/
/*
char* music_ptr = music - 1;//ひとつ手前にしておく
for(t=0; t<musictime; t++){
long p = t%(ptime);
if(p==0) music_ptr++;//次の音符
float frq = GetFrq(*music_ptr);//周波数を得る
long fdtime = (long)(44100/frq);//周波数をサンプル時間に変換
if( (p%fdtime)<(fdtime/2) ) wave_data[t] = 12767; //方形波生成
else wave_data[t] = -12767;
}
*/
long musictime = (long)(lstrlen(music));
short* wave_data=(short*)GlobalAlloc(GPTR,sizeof(short)*musictime);
short* in = (short*)music;
//-------filter----------------------------------------------------
float* out=(float*)GlobalAlloc(GPTR,sizeof(float)*(char)music);
long filter = 0;//フィルターの種類を選択
switch(filter){
case 0:{
//ディレイ
const int DELAY_TIME = 8000;
const float DELAY_LEVEL = 0.4f;
for(t=0; t<musictime; t++){
if(t>=DELAY_TIME) out[t] = in[t] + out[t-DELAY_TIME]*DELAY_LEVEL; //ディレイの出力信号 = 入力信号 + 読み出したバッファの値
else out[t] = in[t];
}
}break;
case 1:{
//ローパス
const float LOW_PASS = 0.80f;
for(t=1; t<musictime; t++){
out[t] = in[t] + (out[t-1]-in[t])*LOW_PASS;
}
}break;
case 2:{
//ハイパス
const float HIGH_PASS = 0.80f;
for(t=1; t<musictime; t++){
out[t] = in[t] - in[t-1]*HIGH_PASS;
}
}break;
/*
case 3:{
//レゾナンス
const float RESO = 0.1f;
const float LOW_PASS = 0.8f;
float v0=0,v1=0;
for(t=1; t<musictime; t++){
v0 = (1.0f - RESO*LOW_PASS)*v0 + (in[t]-v1)*LOW_PASS;
v1 = (1.0f - RESO*LOW_PASS)*v1 + LOW_PASS*v0;
out[t] = v1;
}
}break;
*/
}
//出力
for(t=0; t<musictime; t++){
if(out[t]> 32767.0f) out[t] = 32767.0f;
if(out[t]<-32767.0f) out[t] = -32767.0f;
wave_data[t] = (short)out[t];
}
fclose(fp);
//-----------------------------------------------------------------
//WAVEデバイス設定
WAVEFORMATEX wf; //WAVEFORMATEX 構造体
wf.wFormatTag=WAVE_FORMAT_PCM; //これはこのまま
wf.nChannels=1; //モノラル ステレオなら'2'
wf.nSamplesPerSec=44100; //44100Hz
wf.wBitsPerSample=16; //16ビット
wf.nBlockAlign=wf.nChannels*wf.wBitsPerSample/8; //計算
wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign; //計算
wf.cbSize=0; //計算
HWAVEOUT hWOut;
waveOutOpen(&hWOut, WAVE_MAPPER, &wf, 0, 0, CALLBACK_NULL);
//WAVE情報設定
WAVEHDR wh;
wh.lpData = (LPSTR)wave_data;
wh.dwBufferLength = sizeof(short)*musictime;
wh.dwFlags = 0;
wh.dwLoops = 1;//1回だけ再生
wh.dwBytesRecorded=0;
wh.dwUser=0;
wh.lpNext=NULL;
wh.reserved=0;
//再生
waveOutPrepareHeader(hWOut , &wh , sizeof(WAVEHDR));
waveOutWrite(hWOut , &wh , sizeof(WAVEHDR));
MessageBox(NULL,"WavePlay","Wave",MB_OK);
ExitProcess(0);
}