어쩌다보니 연구에 OFDM을 써야하게 되었다. 조사한 내용을 정리해본다.

내 사용 목적은 (1)소리로 데이터를 전송하는 것과, (2)녹음된 소리의 Time Sync를 정확하게 맞추기 위함이다.




OFDM (Orthogonal Frequency Division Multiplexing, 직교 주파수 분할 다중화)

직교하는 부반송파(sub-carrier)를 수십~수천 개씩 사용해서 병렬로 정보를 전송하는 기술

기존 기법들은 Single Carrier로써, 주파수 하나만 잡고(예: FM 라디오 등등)데이터를 전송했으나, 단점이 많이 있었음


(carrier와 channel 용어는 서로 섞여서 쓰인다)




장점

  • Multipath 환경에 강하다.
    • 주변 사물에 부딪혀서 여러 번 겹쳐 녹음될 경우, 신호 분리가 까다로운데 이를 해결할 수 있음.
    • Single Carrier 쓸 때는 데이터를 많이 전송하려면 Higher Rate를 썼어야 했고
      그러면 Multipath 환경에서 신호가 너무 쉽게 겹친다. (목욕탕에서 말을 빨리 하는 것과 같음)
    • OFDM은 여러 Carrier에서 데이터를 나눠서 Lower Rate로 전송한다.
      => 한 비트가 오래 유지되니까 알아듣기 쉽고, 앞 신호랑 조금 겹쳐도 그 부분 걍 잘라내면 된다.
  • 특정 채널의 상태가 좋지 않아도, 병렬 전송이라서 영향이 크지 않다.
    • SIngle Channel 였다면 신호가 아예 죽었을 것
  • 대역폭을 굉장히 효율적으로 사용한다
    • Sub-carrier를 겹치게 배치할 수 있으므로

(더 많은 장점은 위키를 참고: https://ko.wikipedia.org/wiki/직교_주파수_분할_다중_방식)




왜 Orthogonal인가?

병렬 전송에 대한 개념으로 FDM이 먼저 나왔으나 단점이 존재했다. 각 sub-carrier들이 겹치지 않아야 했으므로 Guard Band가 필요했다.

결과적으로 대역폭(Bandwidth)를 많이 차치하여 비효율적인 배치가 된다.


근데 어찌어찌 '직교성' 이라는것을 잘 이용하면 sub-carrier들을 겹치게 배치해도 잘 동작하게 된다. 아래처럼...

FDM과 비교했을 때 훨씬 많은 sub-carrier를 이용할 수 있음을 알 수 있다. Guard Band도 없다.




OFDM 채널 배치 구조

한 Carrier의 Amplitude가 최대일 때, 다른 Carrier들의 Amplitude는 0이 되도록 스펙트럼이 절묘하게 겹쳐져 있다. (직교성)

Theoretical BPSK OFDM spectrum



Guard Interval

위에서 Guard Band라는 용어가 쓰였는데, 채널 사이를 분리해 주는 역할이었다. (Frequency domain)
이번 용어는 Guard Interval로 전혀 다른 개념이며, 전송하는 데이터 사이를 분리해 준다. (Time domain)

예를 들어, 사우나에서 한 단어를 말하고 연달하서 다음 단어를 말하면 Multipath에 의해 첫 단어와 두 번째 단어가 겹쳐서 들린다.
그래서 첫 단어를 말하고 잠깐 쉬어주면(Guard Interval) 첫 단어의 Echo가 완전히 사그라 들게 되고, 이 때 두 번째 단어를 말한다.

즉 Guard Interval은 Echo들이 완전히(혹은 충분히) 사그라 들 때까지 기다리는 시간을 의미한다.

아래 그림은 Signal이 Multipath에 의해 3번 수신된 상황을 예시로 든 것이다. 마지막 Reflection까지를 Guard Interval로 설정했다.
물론 Guard Interval은 환경에 따라 매 번 개발자가 직접 지정해 줘야 하는 부분이다. 동굴 안에서는 충분히 길게 해야 할 것이고...




주로 쓰이는 OFDM 송수신부 구조


위 구조에서 Time Sync와 Cyclic Prefix 등은 빠져있음. 실제 구현하려면 위 구조보다 조금 더 복잡함.



Cyclic Prefix

Cyclic Extension (순환 확장)은 Multipath로 인해 발생하는 ISI(Inter Symbol Interference)를 극복하기 위해 고안된 방법이다.

목적은 Sub-carrier 사이의 직교성(Orthogonality)의 파괴를 방지하기 위함이다.

방식은 Cyclic Prefix의 경우 유효 신호의 마지막 부분 신호를 일정 부분 복사해서 앞에다가 삽입한다.


아래와 같은 데이터를 전송한다고 해보자. 3개의 Symbol이 있다.


이를 전송하면 Multipath로 인해서 Delay를 가진 신호들이 여러 번 들어오게 된다. 아래는 Original과 2개의 Multipath를 예로 들었다.

잘 보면 S2의 앞부분이 S1의 Echo와 겹치기 때문에 Inter Symbol Interference가 발생하여 S2를 추출해 낼 수 없게 된다.

따라서 결과를 보면 S2의 앞부분이 손실되고 뒷 부분만 얻어내게 된다.


그래서 Cyclic Prefix를 두게 된다. 어려운 개념은 아니고 Symbol의 뒷부분 일부를 앞에다가 복사하는 것이다.


그리고 신호를 전송해 보면... Multipath로 겹치는 부분이 발생하더라도 결국은 S2 안에서 일어나는 일이기 때문에

Symbol간의 Inter Symbol Interference는 발생하지 않는다는 것을 알 수 있다.




자주 쓰이는 용어 및 개념

  • FFT (Fast Fourier Transform)
    • 시간 도메인 신호를 주파수 도메인으로 바꿔주는 것
  • IFFT (Inverse Fast Fourier Transform)
    • FFT를 역으로 하는것
  • ISI(Inter Symbol Interference), ICI(Inter Channel Interference)
    • Multipath로 인해 신호가 겹쳐 들리는 현상
  • Modulation
    • 신호를 잘 전달하기 위해 적절히 데이터를 변조하는 것 (전자쪽 용어, 신호처리 분야)
    • QPSK, 16-QAM 등등 주로 사용됨
  • Cyclic Prefix
    • Guard Interval(최대 지연시간)동안의 신호를 복사해서 앞에 갖다붙이는 것
    • Guard Interval을 쓰는 이유? Multipath로 신호가 겹쳐봤자 최대 이 시간까지만 겹칠 것이라고 가정하는 것
    • 쉽게 말하면 뒷쪽 신호를 짤라서 앞에 갖다붙이는 것
    • Inter Symbol Interference를 극복하기 위함 - 신호가 어느정도 겹쳐도 걍 CP를 잘라버림 (어차피 뒤에 또 나올거니까)





[출처]

https://ko.wikipedia.org/wiki/직교_주파수_분할_다중_방식 (OFDM 기본 설명 및 장단점)

http://www.whydsp.org/209 (OFDM과 CP에 대한 이해가 쉬운 설명)

https://www.csie.ntu.edu.tw/~hsinmu/courses/_media/wn_11fall/ofdm_new.pdf (영문)(설명이 그림과 함께 아주 잘 되어있음)

https://dsp.stackexchange.com/questions/20132/ofdm-transmitter-bandwidth (영문)(그림 출처)

https://caesarhks.blog.me/70133244891 (OFDM에 대한 간단한 설명)

http://www.ni.com/white-paper/3370/ko (영문)(OFDM에 대한 간단한 설명)

https://www.radio-electronics.com/info/rf-technology-design/ofdm/ofdm-basics-tutorial.php (영문)(OFDM 설명)


http://www.ktword.co.kr/abbr_view.php?m_temp1=3164 (Cyclic Prefix 용어 설명)

http://www.telecomhall.com/what-is-cp-cyclic-prefix-in-lte.aspx (영문)(Cyclic Prefix 기본 개념 설명)


[좋은 코드 예시들]

http://blog.naver.com/PostView.nhn?blogId=ykryu7&logNo=221256145776 (MATLAB. 예시 코드와 설명)(실수, 허수 구조)

http://www.rfwireless-world.com/source-code/MATLAB/OFDM-matlab-code.html (영문)(MATLAB. 단순하며 직관적인 4-channel 코드 예시)

http://www.skydsp.com/publications/4thyrthesis/code.html (MATLAB. WAV 소리 파일로 생성하는 코드. 논문에 사용된 코드라 다소 복잡함)

http://dspillustrations.com/pages/posts/misc/python-ofdm-example.html (Python. 단계별로 아주 자세히 설명해 주는 코드 예시)

http://wisechoding.tistory.com/41 (MATLAB, 단계별 OFDM 시뮬레이션)

공식 설치 메뉴얼: https://www.tensorflow.org/install/install_windows


TensorFlow 설치 전에 먼저 깔아야 하는 것들(Requirements)

- CUDA Toolkit 8.0

- cuDNN v6.1


주의할 점은 위 requirement들을 최신 버전으로 깔면 TensorFlow가 지원을 안함 ㅡㅡ;;

현재 CUDA 9.1과 cuDNN 7이 최신이라 홈페이지 메인에 떡하니 있는데, 좋다고 넙죽 받아서 설치하면 당연 안되고

꽁꽁 숨어있는 Legacy 다운로드 메뉴로 들어가서 굳이 구버전을 깔아야 함


CUDA Toolkit은 크기가 좀 커서 그렇지(1.5GB) 그냥 깔면 되고

cuDNN은 받아서 압축 풀면 dll이 튀어나오는데, 적절히 원하는 폴더에 넣고 환경 변수에 해당 경로를 박아야 함

예를 들어 C:\Program Files\cudnn 폴더 만들고 그 안에 cudnn64_5.dll를 넣었으면 그 경로를 %PATH%에 박고 재부팅ㄱ





TensorFlow가 잘 깔렸는지 확인하는 파이썬 스크립트:

https://gist.github.com/mrry/ee5dbcfdd045fa48a27d56664411d41c#file-tensorflow_self_check-py

[Sampling]

이 세상의 소리(Sound)라는 것은 아날로그이기에 Linear 하다.

그런데 컴퓨터는 디지털이므로 이 Linear한 소리를 Discrete 한 데이터로 변환해야 한다.

 

아날로그는 거의 무한대의 해상도를 가지므로 이것을 그대로 디지털로 표현하는 건 불가능하다.

따라서 그 일부분만 채취(샘플링)하여 최대한 원본과 유사한 디지털 데이터를 만들어야 한다.

이러한 과정 또는 행위를 샘플링이라 한다.

 

용어가 몇 개 있다:

(1) 샘플링 레이트(Sampling Rate) : 1초에 몇 개의 샘플을 추출할 것인지

(2) Bit Depth : 한 개의 샘플이 얼마만큼의 정확도/단계를 가지는지

 

샘플링 레이트가 높을 수록 아날로그와 유사한 모양의 데이터를 얻을 수 있다.

아래 그림은 샘플링 레이트에 따른 디지털 데이터의 모양을 나타낸다.

잘게 쪼갤 수록 아날로그의 것과 같이 부드러운 곡선이 되는 것(=원본에 가까움)을 확인할 수 있다.

 

더불어서 각 샘플(sample)이 표현할 수 있는 값의 범위를 sample size 라고 한다.

하나의 샘플이 0부터 1까지의 값을 표현할 것인데 이를 얼마나 정밀하게 표현할 것인가...

예를 들어 샘플 사이즈가 3 bit라면 8단계로 표현 가능할 것이다. (0.0, 0.125, 0.25, 0.375, ...)

(출처: http://www.morphfx.co.uk/music/edu-sampling.htm)

 

따라서 아날로그를 디지털로 샘플링 시 필요한 용량은 Sample Rate와 Sample Size의 곱이다.

 

예를 들어보자. 우리가 일반적으로 구입할 수 있는 음반 CD의 스펙은 44,100 Hz, 16-bit 이다.

이는 1초에 44100개의 샘플을 추출하고, 각 샘플의 크기는 16 bit 라는 것이다.

따라서 둘을 곱하면 705,600 bit가 1초를 표현하는 데 사용된다. (88,200 byte = 86.13 KB)

이론상 4분짜리 곡은 20.15 MB가 필요할 것이다. 실제로 WAV, PCM 등의 무손실이면 이 용량이 나온다.

 

 

[나이퀴스트 샘플링 이론(Nyquist–Shannon sampling theorem)]

왜 대부분의 MP3 파일, 혹은 하드웨어들이 44,100 hz 스펙을 가지고 있는지 대충 납득할 수 있다.

 

이 이론의 결론을 요약하면 다음과 같다:

A sufficient sample-rate is therefore 2B samples/second, or anything larger. 

충분한 샘플링 레이트는 대역폭의 두 배, 혹은 그 이상이다.

 

더보기

우선 앨리어싱(Aliasing)이라는 개념이 있다.

원본을 샘플링하여 새로이 구성된 데이터가 원본과 다를 때 발생하는 왜곡이나 아티팩트를 의미한다.

 

샘플링 레이트가 충분히 높지 않다면 샘플된 데이터는 원본 데이터를 충분히 표현하지 못한다. 당연한 말이다.

아래 그림은 벽돌 벽(원본)을 사진(샘플링)으로 촬영한 사진이다.

 

충분히 큰 해상도로 촬영하여, 벽돌의 규칙적인 모양을 잘 표현한 사진

  

낮은 해상도로 촬영하였기에 벽돌의 연속적인 패턴을 제대로 표현하지 못하는 모습

 

이 건물은 벽돌이 연속성을 가지고 배치되어 있다.

그런데 낮은 해상도로 사진을 찍을 경우 벽돌의 연속성을 제대로 표현하지 못하고 원본과 다른 왜곡된 모습을 표현하게 된다. 마치 시멘트가 좀 더 많이 발려진 것 같이 보인다.

 

이유는 갈색 벽돌 부분과 흰색 시멘트라는 두 요소를 조화롭게 샘플링해야 하는데

샘플링 비율이 한 쪽에 치우치게 되면 원래의 모양이 왜곡된 것처럼 보이는 것이다.

 

그런데 무조건 이 문제가 생기는 것은 아니고...

정말 재수가 좋아서 원본의 특징점을 잘 샘플링 할 경우... 딱히 문제가 없을 수도 있다.

혹은 눈속임으로 샘플들 사이를 비벼버리는 테크닉도 있다. (anti-aliasing)

 

시그널 프로세싱은 이러한 아다리를 지향한다고 할 수 있다.

어떻게 하면 최대한 적은 샘플링으로 원본의 특징을 그대로 살릴 수 있을지...

이와 관련하여 나이퀴스트는 Aliasing이 발생하지 않는 샘플링 레이트를 대역폭의 2배라고 제시한 것이다.

 

관련해서 자세한 내용은 관련 논문 참고:

http://medialab.sjtu.edu.cn/teaching/DIP/Projects/chapter_bas/ShannonTheoremTutorial.pdf

 

사람이 소리로 들을 수 있는 가청 주파수의 범위는 20~20,000 Hz 으로 알려져 있다. (나는 16,000 까지밖에 안들리던데...)

즉 데이터의 대역폭이 20 KHz라는 것인데, 이를 왜곡(Aliasing 등) 없이 샘플링 하려면

대역폭의 2배인 40 KHz 샘플링 레이트 이상으로 샘플링 해야한다는 이론이다.

 

하지만 이론상의 최소 요구가 2배라는 것이고, real-world에서는 8배 정도가 안전하다는 얘기를 엔지니어들이 종종 한다.

그렇기 때문에 192 kHz 까지 사용하는 Hi-Fi 업계가 존재하는 것으로 보인다.

 

현재는 44,100Hz와 48,000Hz가 범용적으로 가장 많이 사용되고 있다.

44,100hz : 25FPS PAL, 30FPS NTSC

48,000hz : 29.97FPS NTSC

 

 

 

[Sources]

https://en.wikipedia.org/wiki/Sampling_(signal_processing)

https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem

https://en.wikipedia.org/wiki/Aliasing

+ Recent posts