Skip to content

Instantly share code, notes, and snippets.

@StarJade-Park
Last active July 9, 2017 05:14
Show Gist options
  • Save StarJade-Park/d0ec767565ee865753db03cae696b148 to your computer and use it in GitHub Desktop.
Save StarJade-Park/d0ec767565ee865753db03cae696b148 to your computer and use it in GitHub Desktop.
[2nd order IIR] 2nd order IIR(Infinite-duration Impulse Response) #matlab #2nd_IIR #C #Multimedia_Systems
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// def const val
#define SAMPLING_BIT 16
// def struct confficients for IIR
typedef struct __IIRConfficients {
double b0, b1, b2;
double a1, a2;
} __IIRConfficients;
// def struct sound file(.snd) information
typedef struct __RawFileInfo {
char* file_name;
int sample_bit;
} __RawFileInfo;
// def struct i/o file ptr
typedef struct __ioFile {
FILE* fi;
FILE* fo;
} __ioFile;
// file open function
__ioFile file_open(__RawFileInfo input, __RawFileInfo output) {
// init file ptr
__ioFile _ioFile = { NULL, NULL };
fopen_s(&_ioFile.fi, input.file_name, "rb"); // 녹음한 오디오 화일을 연다
fopen_s(&_ioFile.fo, output.file_name, "wb"); // 출력을 저장할 화일을 연다
if (_ioFile.fi == NULL && _ioFile.fo == NULL) {
fputs("file err, press any key.", stderr);
getchar();
exit;
}
return _ioFile;
}
// 2nd order IIR filter function
void second_order_IIR_filter(__RawFileInfo fi, __RawFileInfo fo, __IIRConfficients conf)
{
// file open
__ioFile _ioFile = file_open(fi, fo);
int i;
int N;
__int16 input, output;
//init x, y
float x[3] = { 0, 0, 0 };
float y[3] = { 0, 0, 0 };
//get file byte size
fseek(_ioFile.fi, 0, SEEK_END);
int file_size = ftell(_ioFile.fi);
fseek(_ioFile.fi, 0, SEEK_SET);
// 루프횟수 N = 화일에 들어 있는 샘플 수
N = file_size / (fi.sample_bit / 8);
// filtering
for (i = 0; i < N; i++) {
x[2] = x[1]; // x[n] 어레이를 한 샘플씩 delay 시킨다.
x[1] = x[0];
y[2] = y[1]; // y[n] 어레이를 한 샘플씩 delay 시킨다.
y[1] = y[0];
// 입력 PCM(16비트 정수)을 읽어서 x[0] 위치에 넣는다
fread(&input, sizeof(__int16), 1, _ioFile.fi);
x[0] = (double)(input);
// y[n]을 계산한다
y[0] = conf.b0 * x[0] + conf.b1 * x[1] + conf.b2 * x[2]
- conf.a1 * y[1] - conf.a2 * y[2];
// 출력을 16bit PCM 형태로 화일에 저장한다.
output = (__int16)(y[0]);
fwrite(&output, sizeof(__int16), 1, _ioFile.fo);
}
//close input, output file
fclose(_ioFile.fi);
fclose(_ioFile.fo);
}
// main function
int main()
{
// init vals
__RawFileInfo file_input = { "sound.snd", SAMPLING_BIT };
__RawFileInfo high_pass_filter = { "high_pass_filter.snd", SAMPLING_BIT };
__RawFileInfo low_pass_filter = { "low_pass_filter.snd", SAMPLING_BIT };
// vals get using matlab(butter function)
__IIRConfficients HPF = { 0.0604985076309406, 0.120997015261881, 0.0604985076309406, -1.19391336772058, 0.435907398244341 };
__IIRConfficients LPF = { 0.569035593728849, -1.13807118745770, 0.569035593728849, -0.942809041582064, 0.333333333333333 };
// filtering
second_order_IIR_filter(file_input, high_pass_filter, HPF);
second_order_IIR_filter(file_input, low_pass_filter, LPF);
// end
printf("End of program, press any key...\n");
getchar();
return 0;
}
clc; % Clear the command window.
clear; % Clear workspace variable
close all; % Clear figure windows
% low pass filter
fs = 16000;
fn = fs/2;
fc = 1500;
n = 2;
ftype = 'low';
[lB, lA] = butter(n, fc/fn, ftype);
% high pass filter
fs = 16000;
fn = fs/2;
fc = 2000;
n = 2;
ftype = 'high';
[hB, hA] = butter(n, fc/fn, ftype);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment