DSP

TMS320C6748 을 활용한 DSP_ FIR&IIR (LAB8)

알 수 없는 사용자 2021. 2. 3. 11:55
반응형

<이 내용은 강원대학교 전자공학과 실시간 신호처리 과목에서 진행된 내용을 기반으로 작성되었습니다.>

 

 

LAB8

 

이제 정말 DSP를 할 순서가 왔다. 기존에 만든 시스템을 활용하여 정말 실시간 신호처리를 할 것이다. 만약 DSP에 대해 조금 공부해봤다면 DSP의 가장 기초는 푸리에변환임을 알 것이다. 그리고 푸리에변환을 위해서는 이전 값들을 알아야 한다는 사실 또한 알 것이라 생각한다. 이 푸리에 변환을 하기 위해 filter.c라는 파일에 FIRFilter를 만들어 넣었다.

 

 

이 함수는 푸리에 변환에 필요한 이전 값들을 dbuff 즉 딜레이 버퍼를 사용하여 저장해둔다. x[i]는 지금 들어온 값 즉 현재 값으로 매번 들어올 때마다 딜레이 버퍼의 내용은 뒤로 미루도록 짜여 있다. , dbuff[1]의 값은 하나 과거의 값이고, 새 값은 dbuff[0]에 저장하는 것이다. 이 때 FIRFilter의 인자들은 각각 X는 입력 값, h는 필터 계수, r은 출력 값, dbuff는 디버프, nh는 필터 계수의 크기, nx는 입력 값의 크기이다.

 

입력은 기존에 만든 코드들을 활용해 in_L이나 in_R 배열을 넘겨주면 될 것이다. 그리고 자연스럽게 출력 값 또한 out_L이나 out_R이 될 것이다. 그리고 그에 따라 nx는 기존 배열의 크기였던 BUFLEN이 될 것이다. 자 이제 나머지 값들에 대한 의문점이 생긴다. 필터 계수는 어디서 얻어야 하며 디버프는 어떻게 만들어야 할까?

 

이를 위해 MATLAB을 사용하자. MATLAB에는 fdatool이라는 명령어로 제공되는 필터 디자이너가 있다. 매트랩에 fdatool이라고 치면 다음과 같은 화면이 뜬다. (만약 뜨지 않는다면 앱 -> 추가 앱 다운로드 -> signal processing toolbox 검색 후 다운로드를 하면 된다.)

 

 


자세히 보면 lowpass필터, highpass필터, 그리고 각각에 대한 IIR필터들과 FIR필터들을 선택하여 원하는 주파수 사양에 맞추어 필터를 디자인 할 수 있다. 우선 lowpass필터를 만들어 보자. FIR필터들 중 가장 성능이 좋은 Equiripple을 사용하여 다음과 같은 주파수 사양을 맞추어 보았다.

 

우리는 지금 16비트 48000Hz의 소리파일을 기준으로 필터를 만들 것이므로 Fs48000, 그리고 약 3000정도로 제한을 두고자 하여 Fpass3000, Fstop3200으로 잡아보았다. 그리고 dB의 제한은 70으로 잡았다. 이때 원하는 스펙의 필터 차수가 홀수가 되도록 필터를 맞춰야 한다.


필터 설정을 끝냈으면 위의 대상 -> C 헤더 생성을 클릭하자. 그러면 창이 하나 뜰 것이다.

 

우리는 필터를 h라는 이름으로 만들 것이다. 또한 그 길이를 N으로 설정하고자 한다. 이에 맞게 바꾸어 생성 버튼을 누르면 어디에 저장할지 디렉토리를 결정하는 창이 뜰 것이다. 프로젝트의 workspace를 찾아 알맞은 디렉토리에 저장하자.


그리고 다시 CCS로 돌아와 디렉토리를 보면 fdacoefs.h 파일이 생겼을 것이다. 해당 파일을 우리가 사용하기 쉽도록 조금 수정하고자 한다. 현재 우리는 h , FIR의 계수를 float형태로 계산하는 코드를 가지고 있다. 그리고 전체 필터의 크기는 N으로 define하여 다른 곳에서 쉽게 참조할 수 있도록 하자.

 

 


그 외에 다른 코드는 다 지워도 된다.

 

이제 해당 필터 크기만큼의 딜레이버퍼를 선언하면 된다.

 

 


버퍼를 초기화 시켜주는 동작까지 만들었다. 해당 함수는 버퍼를 0으로 초기화 시켜준다.

 

이제 버튼이 눌렸을 때 생성된 FIR필터에 따라 LowPass필터가 작동될 것이다. 한번 해보도록 하자.

 

LAB8_A

 

 혹시 위에서 만든 필터를 차수를 높여본 사람이 있다면 재미있는 현상을 마주했을지도 모른다. 대략 600차수쯤 되면 보드가 멈추는 현상이 발생할 것이다. 보드의 한계는 그것밖에 안 되는 것일까? 그리고 그게 최선일까?


 http://software-dl.ti.com/sdoemb/sdoemb_public_sw/dsplib/latest/exports/exports/dsplib_c64Px_3_4_0_0_Win32.exe 해당 링크를 통해 dsplib_c674x_3_4_0_0_Win32를 받을 수 있을 것이다. 다운받아 ti 밑에 설치하도록 하자.

 

설치가 끝난 뒤 CCS로 돌아가 Window -> Preferences -> Code Composer Studio -> Products를 클릭하자.

 

 


해당 창에서 Rediscover를 클릭하면

 

 

 


다음과 같이 창이 뜬다. Install을 클릭한다. 혹시 뭔가 창이 뜬다면 install anyway를 눌러주면 된다. 설치가 끝나면 CCS를 다시 시작하게 된다. 그러면 설치가 완료된 것이다. 자 이제 해당 DSPLIB을 적용할 프로젝트를 들어가자. 프로젝트의 Properties를 통해 사진과 같이 설정한다.

 

 

 

 


, 이제 설정이 끝났다. 이 설정들은 모두 ti에서 제공해주는 함수들을 사용하기 위한 것이다. DSPLIB이 설치된 파일 디렉토리로 들어가 다음 파일을 살펴보자.

DSPLIB_Users_Manual라는 이름의 파일을 들어가면 화면이 하나 뜰 것이다. 여기서 Getting Started란에 있는 API Reference에 들어가면 여러 함수들을 볼 수 있다.

 

 함수들은 모두 DSPLIB가 제공해주는 함수들이다. 이 함수들은 어셈블리 코드로 작성되어있다. 따라서 매우 빠르다. 성능이 좋다. 기존 코드에 비해 수배의 효과를 나타낸다. 4000차까지도 돌아갈 것이다. 한번 살펴보자.

 


 함수를 사용할 것이다. 그런데 밑에 뭔가 쓰여져 있다.

 

이 함수를 사용하기 위한 조건이 쓰여져 있다. 보면 xydouble-word aligned이여야 한다. 이 말은 8의 배수여야 한다는 것이다. 그리고 nx , 필터 차수는 8의 배수이고 8보다 커야 한다.


따라서 이러한 조건을 맞춰야 한다. 우선 필터에 따라 나온 헤더 파일을 살짝 변경하자.

 

우선 #pragma DATA_ALIGN( L_dbuff, 8 ); 이걸로 h 8의 배수로 맞춰준다. 지금은 N의 개수가 1216으로 N이 딱 8의 배수인 상황이다. 만약 8의 배수가 아니라면 h는 대칭적인 구조이므로 앞뒤에 0을 채워 넣어주어서 8의 배수로 만들어 주면 된다.

 

이제 조건을 만족시켰으므로 FIRfilter를 수정할 수 있게 되었다.

 

 

이렇게 쓴 함수는 약 1500차까지 잘 동작한다. 하지만 사람의 욕심은 끝이 없다. 더 정교하게 만들어진 함수를 찾아보자.

 


해당 함수는 FIR필터를 사용할 수 있도록 제공해준다.

 

 

 


역시나 여러 조건들이 붙어있는 것을 확인 할 수 있다. 그리고 float 배열을 넘겨줘야 한다는 사실 또한 알 수 있다. 따라서 r을 만들어 넘겨줘야 할 것이다. static float r[BUFLEN]; 을 선언해줘 넘겨주면 된다.

 


다음과 같이 함수를 선언한 뒤,

이렇게 코드를 수정하면 4000차까지도 실행이 가능할 것이다. 엄청난 성능 향상이다.

 

 

 

LAB8_B


이번엔 IIR필터를 사용해 보자. IIR필터에는 a, b계수가 존재한다. 우리가 사용할 IIR필터는 Direct Form II이므로 다음 그림과 같은 구조를 가지고 있다.

 


따라서 a계수는 2, b계수는 3개가 있을 것이다. 이에 맞는 구조체를 하나 선언하자.

 

f_coef라는 이름의 구조체는 a, b계수를 가지고 있다. 이 형태를 잘 기억해두길 바란다.

매트랩을 활용하여 IIR필터를 C헤더파일로 만들면 다음과 같은 파일이 생성된다.

이 파일의 차수는 5이다. 따라서 5개의 f_coef , 2개의 a계수와 3개의 b계수로 이루어진 필터가 5개 놓여진 형태를 가진다. const real64_T NUMb계수이다. 그리고 const real64_T DENa계수이다. 그런데 지금 b계수를 나타내는 NUM11개로 이루어져 있다. 가장 마지막은 {1,0,0}인데, 이를 제외한 2개씩의 묶음이 하나의 필터에 대한 b계수를 나타낸다. 예를 들어 {0.724, 0, 0} {1, -1.797, 1} 이 두 개를 통해 b계수 3개를 알아낼 수 있다. 두 배열을 곱하면 된다. 그 곱의 결과는 {0.724, 0.724*(-1.797), 0.724}가 될 것이다. 3 값이 b계수가 되는 것이다. a계수도 마찬가지이다.

이런 계산을 통해 총 5개의 필터에 대한 a계수와 b계수를 구하면 다음과 같아진다.

 

 


 값들을 통해 IIR필터를 돌리면

이런 형태로 만들어 낼 수 있을 것이다.

IIRFilter가 잘 동작하는지 확인해 보기 위해 다음과 같이 코드를 짜 보았다.

 

 

들어오는 입력신호에 1500헤르츠 부분에 sine이 섞인 신호를 만든 뒤, 버튼을 눌러 IIRFilter를 작동시켜 해당 부분을 없애는 동작을 하도록 만들어 보았다.

자 이제 MATLAB에서 추가 앱 다운로드를 통해 DSP System Toolbox를 다운받자. 그러면 노칭이라는 항목이 생길 것이다.

 

 


해당 필터는 딱 1500 부분을 제거해주는 역할을 한다. 이 필터를 C 헤더로 생성하면 다음과 같이 생성된다.

 

이번에는 SOS가 아닌 단일 섹션이기 때문에 a계수와 b계수를 있는 그대로 읽어내면 된다.

이렇게 코드를 작성한 뒤 프로그램을 작동시켜보자. 버튼을 누르면 필터가 작동하여 음악이 들리는 것을 확인할 수 있다.

반응형