티스토리 뷰

기타

MP3 디코더를 만들어 보자!

rlj1202 2016. 1. 4. 14:47

원본 자료: http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html

MP3 디코더를 만들어 보자!


MP3가 지구상에서 가장 잘 알려진 파일 포맷이고 코덱일지 모르지만, 많은 프로그래머들이 이해하기 힘든 것 중 하나라는 것 만큼은 확실할 겁니다. - 가령 표준 라이브러리와 운영체제 커널 같은 것들처럼? 이 글은 신호처리를 위한 짧은 절차 지향 설명과 필요하다면 정보 이론으로 디코더를 최대한 쉽게 설명하려고 노력했습니다. 추가로, 작지만 최소한의 기능을 갖춘 디코더를 하스켈 언어로 작성해 볼 것 입니다.


이 글의 주요 목적은 MPEG 팀이 코덱을 디자인 할 때 만든 콘셉트와 디자인입니다. - 별로 흥미롭지 않은 구현에 관한 디테일과 어려운 이론에 대해서는 다루지 않습니다. 디코더의 몇몇 부분은 꽤 신비롭고 신호 처리에 관한 좋은 책과 MP3에 관한 여러 문서들에 나오는 설명을 읽음으로써 이해하는데 더 쉬울 것입니다. (참조 문헌은 글 끝 단락에 적어두었습니다.)


코드에 대한 메모: 이 글에서 만들게 될 디코더는 가독성을 위해 쓰여졌습니다. 속도를 고려하지 않았습니다. 추가로, 몇몇의 잘 쓰이지 않는 기능은 들어가지 않았습니다. 효율이 떨어지고 표준을 따르지 않지만 이해하기 쉽기를 바랍니다. 소스 코드는 여기서 다운받으실 수 있습니다: mp3decoder-0.0.1.tar.gz. 스크롤을 내려 맨 아래 단락을 보시거나 README 파일을 확인하시길 바랍니다.


중요한 경고: 글쓴이는 취미로 프로그래밍을 하는 사람입니다. 만약, 오류를 발견하신다면 다음 이메일로 알려주세요: be@bjrn.se


자 그럼, 우리의 귀와 함께 여정을 떠나봅니다!



사람의 청각과 음향 심리학


MP3 인코딩과 일반적으로 쓰이는 오디오 손식 코딩의 주된 아이디어는 크기를 줄이기 위해 음성 신호로 부터 청각적으로 쓸모없는 정보를 지우는 것 입니다. 인코더가 하는 일은 신호로 부터 부분 또는 전체적인 정보를 지우면서 들리는 것에는 다름이 없게 하는 것 입니다.


사람의 청각의 몇몇의 특징(또는 단점)은 오디오 손실 코덱에 사용됩니다. 하나의 기본적인 특징은 사람은 20kHz 보다 높거나 20Hz 보다 낮은 소리는 들을 수 없다는 것 입니다. 추가로, 청각의 한계가 있습니다. - 신호가 어느 특정한 한계 아래로 내려가면 우리는 그 소리를 들을 수 없습니다. 너무 조용하기 때문입니다. 이 한계점은 주파수에 따라 다양하게 존재합니다; 20Hz 의 소리는 60 데시벨 보다 높을 때만 들을 수 있습니다. 1-5kHz 의 소리는 소리가 작아도 쉽게 들을 수 있습니다.


청각 시스템에 끼치는 가장 중요한 특징은 마스킹입니다. 매우 큰 소리는 다른 소리들을 묻히게 할 수 있습니다. 이것이 바로 마스킹 이라고 하는 현상입니다. 큰 소리는 스펙트럼과 템포적으로 비슷한 것들에 대한 청각적 한계에 영향을 끼칠 수 있습니다. 이 특징은 아주 유용합니다: not only can the nearby masked signals be removed; 잘 들리는 신호는 큰 압축으로 발생되는 소음을 덮을 수 있어 더욱 더 압축될 수 있습니다.


이 마스킹 현상은 크리티컬 대역폭으로 알려진 주파수 영역에서 발생합니다. 크리티컬 대역폭에 있는 강한 신호는 그 대역폭 안에 있는 주파수들을 마스킹 할 수 있습니다. 우리의 귀를 대역폭 필터들의 집합으로 볼 수 있습니다. 우리 귀의 각 부분은 서로 다른 주파수 영역을 잡아냅니다. 청각 학자 또는 음향학 교수들은 이 마스킹 효과에 대한 미묘한 부분들과 크리티컬 대역폭에 대해 말할 것들이 많겠지만, 이 글에서는 단순화한 엔진이어링 접근만을 취할 것 입니다. 우리의 목적을 위해서 마스킹 효과가 일어나는 고정된 주파수 영역으로써의 크리티컬 대역폭을 생각해 보기에 충분합니다.


인간의 청각 시스템의 특징들을 이용합으로써, 손실 코덱과 인코더는 정보를 줄이기 위한 잘 들리지 않는 신호들을 지울 것 입니다. MP3 표준은 어떻게 인코더를 써야 하는지 설명하고 있지는 않습니다. 이를 구현하는 사람들은 사람들이 감지할 수 없다고 생각하는 부분을 삭제 할 수 있는 많은 자유가 있습니다. 한 인코더는 어떤 주파수는 잘 들리지 않으므로 삭제할 수 도 있고, 다른 인코더는 그 주파수를 삭제하지 않을 수도 있습니다. 서로 다른 인코더들은 서로 다른 음향학 모델을 사용합니다. 그 모델은 어떻게 인간이 소리를 인식하고 어떤 정보가 삭제 되어도 됀찮은지에 대해 설명합니다.



MP3에 대해


MP3를 디코딩 하기 이전에, MP3 가 정확히 무엇인지 이해할 필요가 있습니다. MP3는 공식적으로 MPEG-1 Audio Layer 3로 알려진 코덱 입니다. 그리고 이것은 MPEG-1 표준으로 정의되어 있습니다. 이 표준은 세 개의 서로 다른 코덱으로 정의됩니다. Layer 1 은 가장 간단하지만 가장 낮은 압축률을 가지고 있고 layer 3 는 가장 복잡하지만 가장 좋은 압축률과 비트 레이트 당 가장 좋은 품질을 가지고 있습니다. Layer 3 는 layer 2를 기반으로 하고 있고 layer 2 는 layer 1 은 기반으로 하고 있어 이 세 개의 코덱은 비슷한 점들을 공유하고 있고 또한 인코딩/디코딩 부분에 대해 공통인 부분을 가지고 있습니다.


이 디자인 선택은 MPEG-1 표준이 처음 쓰여졌을 때에는 확실히 이치에 맞았습니다. 세 개의 코덱 사이에 있는 비슷한 점들은 구현하는 사람들에게 편의성을 제공했습니다. 하지만 뒤늦게 보니, 다른 두개의 layer 위에 layer 3를 만드는 일은 가장 좋은 생각은 아니었습니다. MP3의 많은 고급 기능들은 꾸역꾸역 채워졌고 더 복잡해 졌습니다. 사실, AAC의 많은 기능들을 MP3 에서 대응 하는 부분에서 보다 "간단해" 지도록 디자인 되었습니다.


매우 높은 단계에서, MP3 인코더는 이렇게 작동합니다: 변환하고자 하는 WAV 파일을 인코더에 넣습니다. 신호를 시간 단위로 쪼개어 각각 별개의 변환 과정을 거치도록 합니다. 인코더는 나누어진 신호들 중 하나를 가져와 주파수 단위로 나눕니다. 음향학 모델에 근거하여 마스킹 효과 등의 현상을 바탕으로 가능한 많은 정보를 지우게 됩니다. 적은 정보로 바뀐 주파수 샘플은 무손실 압축 과정을 거치게 됩니다. 이제 압축된 샘플들과 그 샘플들이 어떻게 압축 되었는지에 대한 정보를 또한 같이 바이너리 파일로 쓰여지게 됩니다.


디코더는 이 반대 방향으로 작동합니다. 바이너리 파일을 읽고 주파수 샘플을 압축 해제하고 어떤 모델에 의하여 어떻게 정보가 삭제되었는지에 대한 정보를 가지고 샘플들을 재조합합니다. 그런 다음 그것들을 시간 순서대로 다시 변환합니다. 그렇다면, 먼저 바이너리 파일 포맷 부터 시작해 봅시다.



디코더 1 단계: 데이터 분석하기(데이터를 읽는 감각 기르기)


많은 컴퓨터 사용자들은 MP3 가 연속된 데이터 블럭의 집합인 "프레임"들로 만들어졌다는 것을 알고있습니다. 프레임들은 비트 스트림을 언팩킹 하는데 중요하지만 핵심적이지는 않고 또 개별적으로 대코딩 될 수 없습니다. 이 글에서는 무엇이 우리가 물리적 프레임이라고 부르는지, 실제로 디코딩 될 수 있는 데이터들의 집합을 논리적 프레임 또는 그냥 프레임 이라고 하는지 알아보겠습니다.


논리적 프레임은 많은 부분들을 가지고 있습니다: 비트 스트림에서 다른 데이터들과 쉽게 구분되는 4 바이트의 헤더를 가지고 있고, 17 바이트 또는 32 바이트의 사이드 인포메이션, 그리고 몇 백 바이트로 이루어진 메인 데이터를 가지고 있습니다.


물리적 프레임은 헤더와 선택적인 2 바이트의 checksum, 사이드 인포메이션, 매우 희귀한 경우가 아니면 메인 데이터를 가지고 있습니다.

'기타' 카테고리의 다른 글

삼성 NT300VA SSD·멀티부스트 장착  (0) 2017.02.17
그래들(Gradle)의 그루비 문법.  (0) 2016.08.14
어릴적 주운 이상한(?) 돌  (3) 2015.04.01
새 컴퓨터 구입!!!  (1) 2014.12.15
LWJGL 3 가 나온다...!  (0) 2014.12.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday