Skip to content

Instantly share code, notes, and snippets.

@ttsuki
Last active July 19, 2016 15:29
Show Gist options
  • Save ttsuki/720af41136611e9b6a43d421a0902a3f to your computer and use it in GitHub Desktop.
Save ttsuki/720af41136611e9b6a43d421a0902a3f to your computer and use it in GitHub Desktop.
BiQuadIIRによるLPF
#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);
}
};
#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