오디오 CD의 구조
ATAPI에서는 오디오 CD를 재생하기 위한 별도의 명령을 준비해 두고 있다. 이 부분에 대한 자세한 표준은 SCSI의 MMC에 정의되어 있다. 기본적인 원리와 명령 수준의 기능을 구현하는 정도에서 정리하고, 마무리하도록 하겠다.
오디오 CD가 처음 개발된 것은 1978년 경인데, 이미 역사가 25년을 넘어서고 있다. 오래된 만큼 새삼 기술적인 것을 다루기에는 진부한 느낌이 들지만 CD에 관련된 기술은 모두 오디오 CD를 근간으로 하므로 기본적인 내용은 알아둘 필요가 있을 것이다. 즉 모든 형태의 CD 미디어는 오디오 CD를 기반으로 해서 기능을 부가하거나 확장 하는 형태로 발전되었다(DVD의 경우는 기술 진보에 따라 물리적, 논리적으로 좀더 발전된 미디어이다). CD 미디어의 표준은 초창기에서부터 표준 문서의 표지 커버의 색(?)을 통해 구분하는 관습이 전해져 내려왔다. 그래서 오디오 CD는 레드북, CD-ROM은 옐로우북, 레코딩 미디어의 표준은 오렌지북 등으로 부르게 된 것이다.
오디오 CD를 재생하는 기능을 구현하기 위해서는 먼저 레드북(오디오 CD)의 구조에 대해서 어느 정도 알아둘 필요가 있다. 오디오 CD라고는 하지만 현재 데이터 트랙과 다양한 형태로 결합되어 Mixed-CD, Enhanced-CD 등 여러 형태의 변종이 많이 만들어졌다(오디오 트랙이 포함된 게임 CD, 비디오 클립이 포함된 오디오 CD 등이 이런 예에 해당한다). 우선 오디오 CD의 기본적인 형태를 <그림 2>에 나타냈다. CD는 먼저 안쪽의 리드 인 영역으로부터 시작해 실제 데이터가 있는 프로그램 영역, 그리고 맨 바깥쪽인 리드 아웃의 세 부분으로 이루어진다. 실제 사용하는 부분은 디스크의 대부분을 차지하는 프로그램 영역이지만, 리드 인 부분에도 CD-ROM의 제어를 위한 컨트롤 데이터가 저장되어 있다. 리드 아웃은 아무런 데이터 없이 그저 픽업이 CD 밖으로 밀려나지 않도록 안전장치 정도로 사용된다.
<그림 1> 오디오CD 구성과 서브코드의 예
프로그램 영역은 트랙으로 구분되고 각 위치는 시간 정보로 어드레싱이 이뤄진다. 오디오 CD 규격이 처음 만들어질 때에는 데이터 저장이라는 개념이 없고 단지 음악을 재생하기 위한 용도에 한해 고려되었으므로 특정 위치를 지정하는 어드레싱 방법도 LBA와 같은 논리적 개념이 아닌 물리적 개념, 즉 재생 시간을 기준으로 작성되었다(이를 MSF(Minute, Second, Frame) 어드레스라고 한다). 여기서 프레임이란 44.1KHz 샘플링과 16비트 양자화라는 과정을 통해 생겨난 단위로, 1/75초에 해당하는 데이터의 양을 나타낸다. 따라서 오디오 CD내의 모든 영역은 분과 초, 그리고 프레임이라는 파라미터를 통해 액세스가 가능하다. 하드디스크 드라이브의 CHS 어드레스를 LBA로 고치기 위해서는 각각 서로 다른 디스크 내부 구조에 의해 별도의 정보를 필요로 하지만 MSF는 1분은 60초, 1초는 75프레임이라는 변하지 않는 기준을 통해 쉽게 LBA로 표현이 가능해진다. 즉 한 프레임은 한 섹터 또는 한 블럭을 나타내므로 다음 식을 통해 간단히 계산된다.
LBA_address = M*60*75 + S*75 + F
한편 CD-ROM의 경우는 각 섹터의 헤더 정보라는 것을 통해서 해당 섹터의 어드레스 정보를 알아낼 수 있다. 그러나 오디오 CD의 데이터 자체는 어드레스에 대한 아무런 정보를 가지고 있지 않다. 어드레싱을 위한 정보는 별개의 통로에서 출력되는 ‘서브 코드(Subcode)’라는 데이터를 통해서 얻게 된다(<그림 1> 참조). 서브 코드의 종류에는 P, Q, R, S, T, U, V, W의 8가지가 있는데, P 코드는 트랙간 음악의 휴지 기간을 나타내는 데 사용된다. R부터 W까지의 코드는 예전에는 그래픽 정보 등을 저장하는 용도로 사용되었으나 요즘은 거의 사용되지 않는다. 서브 코드 중에서 핵심은 Q 코드(통상 SubQ라고 함)인데, 현재 위치를 나타내는 정보를 지니고 있으며, CD 내부 제어에서도 중요하게 사용된다.
이제 CD-ROM 드라이브를 통한 오디오 CD의 제어에 대해 알아보기 위하여 관련된 명령을 살펴보기로 하겠다. 순수하게 오디오 CD에 관련된 MMC(Multi Media Command) 명령을 <표 1>에 정리했다. 가장 기본이 되는 재생 명령은 Play Audio로서, 여기에는 3종류가 정의되어 있으나 기본적인 동작은 모두 동일하다. 기타 Pause/ Resume, Stop Play/Scan, Scan 등의 명령은 오디오 CD 플레이어에서 흔히 사용되는 형태와 같으므로 별도로 설명이 필요하지 않을 것이다.
Read Sub-channel은 현재의 서브 채널의 데이터를 리턴하는 명령어이다. 앞서 설명한대로 서브 채널은 현재 재생 중인 트랙의 각종 정보를 나타낸다. 이 정보는 오디오 CD의 특성상 현재 데이터와 완벽한 동기를 이루지는 않으므로 재생 중에 가장 최근에 발생한 서브 채널 데이터를 리턴하게 된다. Read Sub-channel 명령은 패킷으로 전달하는 파라미터 값에 따라 Media Catalogue Number, Track ISRC(International Standard Recording Code) Data 등을 리턴하는 용도로 쓰이기도 한다. 하지만 가장 자주 사용되는 것은 위치를 나타내는 SubQ 정보이다.
또한 중요하게 취급되어야 하는 것 중의 하나는 Read TOC/PMA /ATIP 명령이다. TOC(Table Of Contents, 목차)는 CD의 각 트랙에 대한 재생 정보를 한데 모은 정보로서, CD를 재생하기 위해서는 반드시 필요하다. 따라서 모든 종류의 CD 플레이어는 디스크를 인식한 후 바로 TOC 정보를 읽어 오게 된다. 이를 통해 임의 트랙의 재생, 스킵, 스캔, 프로그램 모드 등의 동작이 가능하게 된다. TOC 외에 PMA, ATIP 등은 별개의 정보로서 주로 CD-R/RW에서 사용된다. 리턴되는 TOC 정보의 형태에도 주어진 파라미터에 따라 기본적인 트랙 정보에서 멀티 세션, CD-TEXT 정보에 이르기까지 매우 다양하다.
<그림 2> Read TOC/PMA/ATIP 리턴정보(format=0)
명령 |
내용 |
Play Audio(10) |
10패킷 형태의 CD 재생 명령. 재생할 블럭의 수가 2바이트 크기로 한정됨 |
Play Audio(12) Play Audio MSF |
12패킷 형태의 CD 재생 명령. 재생할 블럭의 수가 4바이트 크기 MSF 어드레싱 형태로 재생 시작 위치와 끝 위치를 지정하는 명령 |
Read TOC/PMA/ATIP |
오디오 CD의 TOC 정보를 읽어오는 명령 |
Pause/Resume |
일시정지와 다시 재생 기능을 수행 |
Read Sub-channel |
서브 채널 데이터를 읽어오는 명령 |
Stop Play/Scan |
재생, 스캔 동작을 멈추게 하는 명령 |
Scan |
스캔 동작을 수행하게 하는 명령 |
[표1] MMC 커맨드 (for CD-DA)
일반적인 CD-ROM 데이터 디스크의 TOC 정보를 읽으면 대부분 한 개의 트랙에 대한 정보가 리턴된다. 보통 CD-ROM은 데이터 영역이 한 개의 트랙에 전부 정리되기 때문이다. 오디오 재생을 위해서는 다양한 TOC 리턴 정보 중에서 Format Code=0일 때의 정보를 주로 사용한다. Format이 0일 때 리턴되는 정보는 기본적인 트랙의 구성과 시작 위치를 나타내는 것으로, 세부 내용을 <그림 2>에 나타내 보았다. 리턴 정보의 처음 4바이트는 전체 길이와 총 트랙의 수를 나타낸다. 이하 데이터는 트랙의 디스크립터이며, CD에 존재하는 트랙의 수만큼 반복된다.
이제 CD-ROM 드라이브에 오디오 CD를 넣고 Read TOC 명령을 내려보기로 하겠다. 모니터를 기동시킨 보드에 atapi12.c를 컴파일한 atapi2.hex를 다운로드하여 실행한다. <그림 3>의 예는 총 트랙이 14개로 구성이 된 CD로서, 마지막 AA 트랙은 디스크의 끝 부분인 리드 아웃 영역을 나타낸다. 따라서 이 부분의 주소는 프로그램의 끝 부분을 나타내게 된다.
$ rd_toc
Read TOC, format:0
byte cnt=172
TOC length :170
start track :1
last track :20
-track :1
ADR :0
control :0
start addr :0
-track :2
ADR :0
control :0
start addr :400a
...
-track :14
ADR :0
control :0
start addr :3d890
-track :aa
ADR :0
control :0
start addr :527af
이번에는 Play(12) 명령으로 실제 오디오 트랙을 특정 위치부터 재생해 보기로 하겠다. Play 명령에는 파라미터로 재생 시간을 지정하도록 되어 있는데, 한 곡만 재생하는 것이 아니므로 재생 시간은 주어진 위치부터 디스크의 마지막 부분까지 길이를 계산하여 재생한다.
$ play 1
Play(12),track:1,start:0,length:527af
Stat=40
명령을 내리면 전면의 LED가 깜박거리면서 CD 재생이 시작될 것이다(일부 구형 CD-ROM의 경우 Play(12) 명령을 인식하지 못할 수도 있는데 Play(10)이나 Play MSF 명령을 사용하면 된다). CD가 재생 중일 때 Read Sub-channel 명령을 내리면 현재의 위치 정보(SubQ data)를 얻어낼 수 있다. 앞서 설명한대로 이 명령은 몇 가지 다양한 정보를 리턴하도록 되어 있으나, 여기서 구현한 프로그램은 전적으로 SubQ 데이터만 읽어내도록 되어 있다. 리턴되는 정보는 현재 재생 위치의 트랙 번호와 절대, 상대 시간을 나타낸다.
$ rd_subq
Audio status :11
track number :1
index number :1
abs. address : 0:31:12
rel. address : 0:29:12
$ rd_subq
...
abs. address : 0:43:8
rel. address : 0:41:8
$ rd_subq
...
abs. address : 1:5:64
rel. address : 1:3:64
rd_subq 명령을 일정 시간 간격으로 내리면 현재 재생중인 위치에 대한 정보를 연속해서 읽어올 수 있게 된다. PC 또는 일반 CD 플레이어에서 LCD 창의 트랙 시간 정보 표시도 통상 이러한 subQ 정보를 이용해서 표시된다.
이상으로 오디오 플레이어에 대한 설명을 마치기로 하겠다. 여기서는 커맨드 라인에 의한 재생 기능만 보였지만 196 입력 포트에 스위치를 연결하고 명령을 적절히 조합하면 간단한 오디오 플레이어를 만들 수도 있다. 이 부분은 이 정도에서 마무리하도록 하겠다.
출처 : 월간 마이크로 소프트웨어 2003년 8월호