Last active
July 19, 2016 15:29
-
-
Save ttsuki/720af41136611e9b6a43d421a0902a3f to your computer and use it in GitHub Desktop.
BiQuadIIRによるLPF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _USE_MATH_DEFINES | |
#include <math.h> | |
class BiQuadIIR | |
{ | |
double b0, b1, b2, a1, a2; | |
double x1, x2, y1, y2; | |
public: | |
BiQuadIIR(double b0, double b1, double b2, double a0, double a1, double a2) | |
: b0(b0 / a0), b1(b1 / a0), b2(b2 / a0), a1(a1 / a0), a2(a2 / a0), x1(0), x2(0), y1(0), y2(0) | |
{ | |
} | |
double proc(double x) | |
{ | |
double y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; | |
y2 = y1; x2 = x1; y1 = y; x1 = x; | |
return y; | |
} | |
// LPFを作って返す | |
static BiQuadIIR LPF(float sampleFreq, int cutOffFreq, double q = 0.707106781186547524) | |
{ | |
double w0 = 2 * M_PI * cutOffFreq / sampleFreq; | |
double a = sin(w0) / (2 * q); | |
double b = cos(w0); | |
return BiQuadIIR((1 - b) / 2, 1 - b, (1 - b) / 2, 1 + a, -2 * b, 1 - a); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <stdio.h> | |
#include <mmsystem.h> | |
#pragma comment(lib, "winmm.lib") | |
int main(int argc, char *argv[]) | |
{ | |
short *pData; | |
int count; | |
// ヘッダ読み飛ばしてWAVEファイル読む (RIFFで生PCMで余計なタグがなければ、データは44バイト目から) | |
{ | |
FILE *fp = fopen("D:\\test.wav", "rb"); | |
fseek(fp, 0, SEEK_END); | |
count = (ftell(fp) - 44) / 2; | |
fseek(fp, 44, SEEK_SET); | |
pData = (short*)malloc(count * 2); | |
fread(pData, 2, count, fp); | |
fclose(fp); | |
} | |
// 左右それぞれLPFをかける。200Hz以下通す | |
BiQuadIIR iirL = BiQuadIIR::LPF(44100, 200); | |
BiQuadIIR iirR = BiQuadIIR::LPF(44100, 200); | |
for (int i = 0; i < count / 2; i += 2) | |
{ | |
// 要 clipping な気がする | |
pData[i] = iirL.proc(pData[i]); | |
pData[i + 1] = iirR.proc(pData[i + 1]); | |
} | |
// 音出す | |
WAVEFORMATEX wex = {}; | |
wex.wFormatTag = WAVE_FORMAT_PCM; | |
wex.wBitsPerSample = 16; | |
wex.nSamplesPerSec = 44100; | |
wex.nChannels = 2; | |
wex.nBlockAlign = wex.wBitsPerSample * wex.nChannels / 8; | |
wex.nAvgBytesPerSec = wex.nSamplesPerSec * wex.nBlockAlign; | |
wex.cbSize = 0; | |
HWAVEOUT hwo; | |
WAVEHDR hdr = {}; | |
hdr.lpData = (LPSTR)pData; | |
hdr.dwBufferLength = count; | |
MMRESULT ret = waveOutOpen(&hwo, WAVE_MAPPER, &wex, NULL, NULL, CALLBACK_NULL); | |
ret = waveOutPrepareHeader(hwo, &hdr, sizeof(hdr)); | |
ret = waveOutWrite(hwo, &hdr, sizeof(hdr)); | |
getchar(); | |
waveOutClose(hwo); | |
delete[] pData; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment