하드웨어 > MPEG1 Audio Layer3 / mp3 파일구조

TODAY466 TOTAL2,277,855
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 하드웨어 | AUDIO | MPEG1 Audio Layer3 / mp3 파일구조

페이지 정보

작성자 키트 작성일2017-08-25 14:10 조회2,165회 댓글0건

본문

 



MPEG1 Audio Layer3

mp3 파일은 여러개의 AAU(Audio Access Uint)들과 1개의 AudioTag로 이루어져 있다.

AAU AAU AAU ... Audio Tag 

 

각각의 AAU들은 다음과 같은 구조를 가진다.

Header CRC SideInfo Main Data 

 

AAU의 사이즈는 다음과 같다.

144*BitRate/샘플링주파수+Padding 

mp3는 프레임당 1152 비트가 할당되기 때문에 바이트 계산하면 144바이트가 된다. BitRate와 샘플링주파수는 헤더정보에서 얻을 수 있다. 파일 Size가 3985814 바이트이고 샘플링 주파수가 44.1khz, BitRate가 128kbit인 mp3파일의 프레임 Size는 144*128000 / 441000 로 약 417바이트가 되며 프레임당 약 9558바이트의 Size가된다.

 

1. Header 

mp3 파일에는 각각의 AAU마다 헤더가 따로 존재한다. 그러므로 각 AAU들은 독립적으로 decode될 수 있다. 그러나 대부분의 mp3에서 모든 헤더들은 동일하므로, 전체를 디코딩할 시에는 첫 번째 AAU의 헤더만을 읽는다.

Header는 32비트의 길이를 갖고 13개의 항목으로 구성되어 있다.

 

길이설명
11 동기패턴모두 1로 설정 
MPEG Audio Version ID00 - MPEG Version 2.5
01 - reserved
10 - MPEG Version 2
11 - MPEG Version 1(mp3의 경우)
Layer 정의00 - reserved 
01 - Layer III 
10 - Layer II 
11 - Layer I 
Checksum 설정유무0 - Error 체크 있음 
1 - Error 체크 없음 
BitRate
MPEG1 
Layer1
MPEG1 
Layer2
MPEG1 
Layer3
MPEG2
Layer1
MPEG2
Layer2,3
0000 free free free free free 
0001 32 32 32 32 
0010 64 48 40 48 16 
0011 96 56 48 56 24 
0100 128 64 56 64 32 
0101 160 80 64 80 40 
0110 192 96 80 96 48 
0111 224 112 96 112 56 
1000 256 128 112 128 64 
1001 288 160 128 144 80 
1010 320 192 160 160 96 
1011 352 224 192 176 112 
1100 384 256 224 192 128 
1101 416 320 256 224 144 
1110 448 384 320 256 160 
1111 bad bad bad bad bad 
샘플링 주파수 
MPEG1 MPEG2 MPEG2.5 
00 44100 22050 11025 
01 48000 24000 12000 
10 32000 16000 8000 
11 reserved reserved reserved 
Padding bit0 - frame is not padded 
1 - frame is padded with one extra bit 
개별용도비트특별히 사용되지 않음
Channel Mode 00 - Stereo 
01 - Joint Stereo 
10 - Dual Channel 
11 - Single Channel 
확장 Mode(Joint Stereo에서만 사용)
Layer 1,2Layer 3
Intensity
stereo
MS
stereo
00 subbands 4 to 31 off off 
01 subbnads 8 to 31 on off 
10 subbnads 12 to 31 off on 
11 subbnads 16 to 31 on on 
Copyright0 - Audio is not copyrighted 
1 - Audio is copyrighted 
Original0 - 복사본 
1 - 원본 
Emphasis  

2. CRC

CRC Check는 프레임의 오류를 검사하기 위한 정보를 가진다.

 

3. SideInfo 

mp3에서 주요하게 사용되는 압축 알고리즘에는 Scalefactor, Huffman 부호화, 양자화 등이 있다. 실제 각 프레임의 메인데이터를 decoding 하는 데 필요한 정보들을 담고 있다. 

 

길이사이드인포 요소 설명
main_data_end mp3 Player 프로그램의 버퍼상에서 비트스트림의 위치
Private_bits  
Scfsi Scalefactor 디코딩에 사용
12 Part2_3_length 허프만 디코딩에 사용
Big_values 허프만 디코딩에 사용
Global_gain 역양자화에 사용
Scalefac_compress Scalefactor Encoding시에 사용
Blocksplit_flag  
Block_type  
Switch_point  
Table_select 허프만 디코딩에 사용
Subblock_gain 역양자화에 사용
Region_address1 허프만 디코딩에 사용
Region_address2 허프만 디코딩에 사용
Preflag 역양자화에 사용
Scalefac_scale Scalefactor 디코딩에 사용, 역양자화에 사용
Count1table_select 허프만 코딩에 사용

 

다음에 이 정보를 저장하기 위한 자료구조가 있다.

typedef struct { unsigned long part2_3_length;unsigned long big_values;unsigned long global_gain;unsigned long scalefac_compress;unsigned long window_switching_flag;unsigned long block_type;unsigned long mixed_block_flag;unsigned long table_select[3];unsigned long subblock_gain[3];unsigned long region0_count;unsigned long region1_count;unsigned long preflag;unsigned long scalefac_scale;unsigned long count1table_select;}gr_info_s;typedef struct {unsigned long main_data_begin;unsigned long private_bits; struct {unsigned long scfsi[4]; gr_info_s gr[2]; // 메인데이터는 2개의 granule로 구성}ch[2]; }III_side_info_t;

사이드인포의 크기는 채널에 따라 그 크기가 달라지는데 Mono일 경우 136bits, Stereo일 경우 256bits이다.(메인데이터는 2개의 granule로 나누어지고 각각의 granule은 채널로 나뉘어짐) 사이드인포 정보 중에서 granule별 채널별로 갖고 있는 정보가 있기 때문에 채널에 따라서 그 크기가 다른 것이다.

다음은 사이드 인포 정보를 얻기 위한 소스 코드이다.

// Mono : 136 bits (= 17 bytes)// Stereo : 256 bits (= 32 bytes) BOOL get_side_info(uunsigned long channels, III_side_info_t *side_info) {int ch, gr;side_info->main_data_begin = get_bits(9);if (channels == 1) side_info->private_bits = get_bits(5);else side_info->private_bits = get_bits(3);for (ch=0; ch; ch++)="" 8bit="" {="" side_info-="">ch[ch].scfsi[0] = get_bits(1);side_info->ch[ch].scfsi[1] = get_bits(1);side_info->ch[ch].scfsi[2] = get_bits(1);side_info->ch[ch].scfsi[3] = get_bits(1);}for (gr=0; gr<2; gr++) {for (ch=0; ch; ch++)="" {="" side_info-="">ch[ch].gr[gr].part2_3_length = get_bits(12);  side_info->ch[ch].gr[gr].big_values = get_bits(9);  side_info->ch[ch].gr[gr].global_gain = get_bits(8);  side_info->ch[ch].gr[gr].scalefac_compress = get_bits(4);  side_info->ch[ch].gr[gr].window_switching_flag = get_bits(1);  // window_switching_flag 는 blocksplit_flag와 같다.   // mixed_block_flag 는 switch_point와 같다.   if (side_info->ch[ch].gr[gr].window_switching_flag) // 22 bits   {    side_info->ch[ch].gr[gr].block_type = get_bits(2);   side_info->ch[ch].gr[gr].mixed_block_flag = get_bits(1);   side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);   side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);   side_info->ch[ch].gr[gr].subblock_gain[0] = get_bits(3);   side_info->ch[ch].gr[gr].subblock_gain[1] = get_bits(3);   side_info->ch[ch].gr[gr].subblock_gain[2] = get_bits(3);   if (side_info->ch[ch].gr[gr].block_type == 0)    return(FALSE);   else if (side_info->ch[ch].gr[gr].block_type == 2 && side_info->ch[ch].gr[gr].mixed_block_flag == 0)    side_info->ch[ch].gr[gr].region0_count = 8;   else     side_info->ch[ch].gr[gr].region0_count = 7;   side_info->ch[ch].gr[gr].region1_count = 20 - side_info->ch[ch].gr[gr].region0_count;  }   else // 22 bits   {    side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);   side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);   side_info->ch[ch].gr[gr].table_select[2] = get_bits(5);   side_info->ch[ch].gr[gr].region0_count = get_bits(4);   side_info->ch[ch].gr[gr].region1_count = get_bits(3);   side_info->ch[ch].gr[gr].block_type = 0;  }  side_info->ch[ch].gr[gr].preflag = get_bits(1);  side_info->ch[ch].gr[gr].scalefac_scale = get_bits(1);  side_info->ch[ch].gr[gr].count1table_select = get_bits(1);} }return(TRUE);}

4. Main Data 

메인데이터는 실질적인 오디오 데이터가 실려있는 영역을 말한다. mp3의 메인데이터는 한 프레임이 1152개의 Sample 데이터를 갖는다.  

granule은 메인데이터가 처리되는 기본단위다. mp3 부호화 방법중 주파수 등분할 방식인 32 서브밴드 방법이 있다. 각 서브밴드는 18개의 sample 데이터를 갖는다. 32*18 = 576 이라는 크기값이 나오며 이것을 한 개의 granule단위로 처리하게된다.  

mp3는 2개의 granule로 구성되어 1152개의 Sample 데이터를 갖게된다. 각 granule안에서는 채널별로 decoding된다.

 

5. 오디오 태그 (Audio Tag) 

오디오 태그는 AAU의 집합 끝 부분 즉 mp3파일의 마지막 부분 128바이트를 말한다. Artist정보, 곡의 제목, 앨범 Title, 출판년도 등의 mp3파일 전체의 부가정보를 담고 있다. 장르에 대한 인덱스는 생략한다.

길이(byte)설명 
Tag ID 
30 Title 
30 Artist 
30 Album 
Year 
30 Comment
장르 

 

6. mp3 데이터 복원 

3660040649_N7zuwFoT_xBoxReplace_250.png

사이드 인포 디코드 (Side Information Decode) 

SideInfo는 mp3의 실제 음향 데이터인 MainData 부분 앞에 위치하며 압축데이터를 복원할 때 필요한 정보들의 집합체이다. SideInfo 정보를 읽어 각 알고리즘 ②,③,④,⑤,⑥ 에서 사용할 수 있게 재배치한다.

스케일 펙터 디코드 (Scalfactors Decode) 

스케일 펙터는 각 밴드의 샘플 데이터 부호화의 한 과정이다. 하나의 밴드 내의 36개 샘플 데이터(Layer III 의 경우 1152/32 = 36 즉 각 서브밴드 당 36 샘플)는 파형과 배율로 분리된다. 파형을 최대 진폭이 1.0이 되도록 정규화 하는데, 그때의 배율이 스케일 펙터로서 부호화 된다. 이 과정을 거치면 Band의 Sample Data 들은 비슷한 값들끼리 모이게 되고, 양자화잡음의 발생을 제한할 수 있기 때문에 청각심리 효과가 작용하여 이들 잡음이 감지되지 않게 된다. 

적응 비트 할당이란 각 프레임, 각 서브밴드 마다 비트를 조정하는 것을 말한다. 스케일 펙터와 조합해서 크리티컬 밴드(임계대역폭)를 고려한 마스킹 레벨 한도 내에서 양자화를 함으로써 마스킹 효과를 더욱 효과적으로 이용 할 수 있다. 즉 마스킹의 효과로 인하여 인식되지 않는 주파수 대역에 대해서는 비트를 할당하지 않는다. 

허프만 디코드 (Huffman Decode) 

허프만 부호화 테이블을 이용하여 복호화 한다. 이때 사용되는 허프만 테이블은 신호의 통계적 편중을 주파수 대역별로 최적화 하여 만들어진 표준화 테이블이라고 한다. 이는 무손실 압축 방법으로 MPEG, JPEG 등에 주로 사용되는 압축기법이므로 자료를 찾는데 무리가 없을 것이므로 여기서는 그냥 넘어가도록 하겠다. 

역양자화 (Dequantization)

역양자화는 양자화를 복원하는 방법이다. 양자화는 데이터의 손실이 오더라도 사람이 감각적으로 감지하기 힘들게 된다면 어느정도의 데이터에 손실을 가하여 압축률을 높이는 방법이다. 역시 허프만 부호화와 함께 주로 사용되는 기법이다.

IMDCT(Inverse Modified Discrete Cosine Transform) 

MDCT는 시간 영역 데이터를 주파수 영역으로 변환하는 것이므로, IMDCT는 역으로 주파수 영역 데이터를 시간영역 데이터로 복호화 한다. 디코딩과정에서 IMDCT는 전체 처리과정에서 CPU점유율 30%이상 많은 연산을 필요로 한다.

32서브밴드 통합 필터뱅크(32 Subband Synthesis Filter Bank) 

 

크리티컬 밴드 등의 청각특성을 효율적으로 이용하기 위해서는 우선 신호를 주파수 성분으로 나누는 것이 필요하다. 이 때문에 Encoder에서는 전 대역을 32개의 밴드로 등간격 주파수폭으로 세분하여 서브밴드 부호화 하므로 Decoder에서 다시 이를 복호화 한다. 

그러나 통상의 필터로 1/32의 주파수대역을 취하는 경우 이상적인 필터가 아니기 때문에 부 표본화의 시점에서 앨리어싱을 일으킨다. 앨리어싱 잡음을 소거하기 위해 폴리페이즈 필터뱅크라고 불리는 필터를 사용하며 이 방법은 주로 Layer I, II 에서 사용된다. Layer III 에서는 MDCT(Modified Discrete Cosine Transform : 변형이산 여현변화)를 복합적으로 사용하고 있다.

 

7. 참고 자료

============================================================================


 

MPEG 오디오란?
MPEG(Moving Picture Experts Group)은 MPEG 오디오, MPEG 비디오와 MPEG 시스템으로 이루어져 있으며, 그 중에서 MPEG 오디오는 고품질, 고압축 부호화를 위한 ISO/IEC의 표준 방식이다. MPEG 오디오는 MPEG 내에서 동영상 부호화와 병행하여 표준화 작업이 이루어졌으며, 전체 비트율이 약 1.5Mbps가 되도록 구성되었다. MPEG 오디오는 통상적인 명칭이고, 정식 표준번호는 ISO/IEC IS 11172-3 (MPEG-1 오디오)이며, 1992년에 국제 표준으로 제정되었다.

MPEG 오디오는 종래의 압축 부호화 방식에 비해 원음에 가까운 음질을 실현하고 있으며, 기본적으로 60~72분 정도의 CD에 포함된 44.1kHz의 샘플 레이트(sample rate)에 샘플 당 16비트를 가지는 오디오 데이터의 크기를 줄이는 것이 목적이다. 

기존의 디지털 오디오기기에서는 샘플 당 16비트를 사용하고 샘플링 주파수는 38kHz, 44.1kHz, 48kHz의 PCM(Pulse Code Modulation) 부호화가 널리 사용된다. MDCT(Modified Discrete Cosine Transform)와 청각심리 특성을 이용한 고능률의 압축으로 샘플 당 16비트의 기존의 데이타가 약 1.5~3비트로 절감되며 이렇게 압축을 해도 원음과의 차이는 거의 없어 주의 깊게 듣지 않으면 느낄 수 없다. 

사람들은 감소(reduction)와 압축(compression)을 혼동하는 경우가 있다. 감소란 음악을 듣는 사람이 원음과의 차이를 느끼는 것이지만 압축의 경우는 필요 없는 정보를 버리고 필요한 정보로만 음악을 구성하여 음악을 듣는 사람이 원음과 쉽게 구별할 수 없게 하는 것이다. 예를 들면 5와 10을 투자해서 같은 100의 결과를 낼 수 있다면 대부분의 사람들은 5를 투자해서 같은 100의 결과가 나오기를 바란다. 이와 마찬가지로 MPEG의 경우도 작은 크기의 파일에 많은 양의 데이터를 담을 수 있으며, 오디오나 비디오 데이터를 저장하고 사용하는데 보다 효율적이다. MPEG 방식으로 압축하면 8시간 분량의 오디오 데이터를 원음과 동일한 음질로 CD-ROM 한 장에 수록할 수 있다.


MP3 개론
MP3는 MPEG라는 멀티미디어 동영상 처리기술에서, MPEG-1의 오디오 영역에서 레이어Ⅲ를 일컫는 말로, 높은 효율로 압축된 오디오 포맷이다. MPEG-1은 시스템, 비디오, 오디오 영역으로 나뉘며, 그 중에서 오디오 영역은 아래 표와 같이 3개의 레이어로 구성된다. 비트율은 일반적으로 사용되는 값이고, 압축률은 평균 비율을 나타낸다. 레이어가 높을수록 비트율이 낮아지는 것은 그만큼 높은 압축율을 갖고 높은 품질의 오디오 데이터를 실현하기 때문이다. 

<표 1> MPEG-1 레이어
3660040649_N7zuwFoT_xBoxReplace_250.png


MP3 파일 구조
MP3는 프레임 단위 구조다. 한 프레임을 AAU(Audio Access Unit)라 부르는데, AAU는 각각 단독으로 복호화할 수 있는 최소 단위이다. 아래 그림과 같이 MP3는 이런 프레임(AAU)의 집합으로 이뤄져 있다.

<그림 1> MP3 전체 구조도
3660040649_N7zuwFoT_xBoxReplace_250.png


상세한 MP3 파일 구조 
헤더는 32비트의 고정된 영역을 가지고, 레이어와 샘플링 주파수, 그리고 남아있는 프레임 등과 같은 정보를 담고 있다. CRC(Error Detection Code)는 선택사항으로 CRC의 유무는 헤더에서 정의되며, 길이는 16비트이다. 하지만 디지털 오디오 하드디스크 레코딩 시스템에는 사용되지 않는다. 

파일 헤더(32비트)
▪ 싱크 워드 (12 비트) : 모두 1로 설정.
▪ 아이디(1 비트) : 항상 1
▪ 레이어 코드(2비트) : 레이어 Ⅰ, 레이어 Ⅱ, 레이어 Ⅲ를 표현한다.
▪ 보호 비트(1비트) : 에러 체크의 유무, 0인 경우 에러 체크를 함
▪ 비트율 인덱스(4비트) : 모두 0인 경우는 자유 포맷 조건으로 하고 나머지는 32 ~ 448 Kbps를 표현한다. 
▪ 샘플링 주파수(2비트) : 샘플링 레이트는 38 Kbps, 44.1 Kbps, 그리고 48 Kbps로 이루어 진다.
▪ 패딩 비트(1비트) : 슬롯의 수를 나타낸다.
▪ 개별용도 비트(1비트) : 개별이용 비트 
▪ 모드(2비트) : 스테레오, 조인트 스테레오, 듀얼 또는 싱글 채널
▪ 모드 확장(2비트) : 모드 확장에 사용되는 비트
▪ 저작권(1비트) : 저작권의 유무, 1일 경우 저작권 있음
▪ 원본/ 복사본(1비트) : 원본 /복사본, 1일 경우 원본
▪ 엠퍼시스(2비트) : 엠퍼시스 특성을 나타낸다.

사이드 정보

<표 2> 사이드 정보의 구조
3660040649_N7zuwFoT_xBoxReplace_250.png

(1) 메인 데이터 엔드 : main_data_end (9비트) 
메인 데이터의 마지막 비트의 위치를 결정하는데 사용된다. 이 값은 비트 스트림의 메인 데이터 부분에서 다음 프레임의 프레임 헤더 위치로부터 음의 바이트 오프셋(off-set)이다.

(2) 개인 정보 : private_bits(5 비트)
개인적 목적으로 사용될 수 있는 비트이다.

(3) 스케일팩터 선택정보 : scfsi(1비트) 
스케일팩터 선택정보는 단일 스케일팩터 대신에 스케일팩터 그룹선택을 제공하는 scfsi_band를 사용. scfsi는 그래뉼에 스케일 팩터를 제공함.

(4) 그래뉼
▪ Part2_3_length (12비트) : 허프만 부호 데이터와 스케일팩터를 위해 사용되는 메인 데이터 비트의 수를 말한다. 사이드 정보의 길이는 항상 같기 때문에 이 값은 추가 정보의 할당이나 각 그래뉼에서 메인 정보의 시작을 계산하는데 사용된다.
▪ Bic_values(9비트) : 각 그래뉼과 함께 부호화된 다른 허프만 부호 테이블의 스펙트럼 값. 주파수 0부터 나이퀘스트 주파수까지의 전체 주파수는 여러 영역으로 나뉘고, 서로 다른 테이블을 사용하여 부호화된다. 여러 영역으로 나누는 것은 최대 양자화 값에 따라 이루어지며, 높은 주파수는 더 작은 크기를 가지거나 또는 전혀 부호화될 필요가 없다는 가정과 함께 여러 영역으로 나뉜다. 높은 주파수에서 시작할 때는 0과 같은 양자화된 값의 쌍들이 세어지고 이것이 rzero이다. 그리고 –1, 0, 1을 가진 양자화된 값을 4개씩 부호화하며, 이것이 count1이다. 나머지 데이터가 반복되고 끝으로 그 스펙트럼 영역 안에 있는 값들의 쌍의 값은 big_values로 부호화되고, 최대 절대값을 8191로 한다.
▪ Global_gain(8비트) : 양자화기의 스텝사이즈에 대한 정보를 제공한다.
▪ Scalefac compress(4비트) : 다음 테이블에 의한 스케일팩터 전송에 사용될 비트수의 선택.
▪ Blocksplit_flag(1비트) : 일반적으로 타입0 윈도와 다른 위도 사용. 세팅 되면 다른 변수들의 디폴트가 set된다.
▪ Block_type(2비트) : 실제 그래뉼의 윈도 타입.
▪ Switch_point(1비트) : 롱/쇼트 변환의 분기점.
▪ Table_select(5비트) : 신호의 부분적 통계의 최대 양자화 값에 의존하여 다른 허프만 부호 선택.
▪ Subblock_gain(3비트)
▪ Region_address(4비트) : 스펙트럼의 분할은 허프만 코더의 성능 향상을 위해 사용된다.
▪ Region_address(2,3비트) : region3안의 부분적이거나 전체적인 스케일팩터 밴드의 수를 계산한다.
▪ Preflag(1비트) : 양자화된 값의 높은 주파수 증폭을 위한 플래그.
▪ Scalefac_scale(1비트) : 스케일 팩터는 이 값에 의하여 스텝 사이즈를 2또는 루트2로 지수 양자화 한다.
▪ Count1table_select(1비트) : 크기가 1을 넘지 않는 양자화 값을 위한 두 가지 사용 가능한 허프만 부호 테이블을 선택한다.

메인 데이터 
메인 데이터에서는 그래뉼 당 576개의 허프만 부호화된 샘플을 처리하고, 그래뉼은 두개의 채널(channel)로 이루어져 있으며, 채널에는 부호화에 사용된 스케일팩터와 허프만 부호화된 샘플들의 정보를 담고 있다. MP3 파일의 메인 데이터의 구조는 <그림4>와 같다.

<표 3> MP3 파일의 메인 데이터의 구조
3660040649_N7zuwFoT_xBoxReplace_250.png

메인 데이터에 사용되는 요소로 다음과 같은 것들이 있다.
▪ Scalefac : 스케일 팩터는 양자화 잡음을 특징짓는데 사용된다.
▪ Huffmancodebits : 절대값 15보다 작게 양자화된 값들은 허프만 부호화되며, 항상 값 (x, y)의 쌍으로 부호화되며, 만약 15보다 큰 값이 양자화되면 ESC코드가 이 값의 플래그로 사용된다.
▪ Ancillary_bit (1비트)


오디오 태그
MP3 는 프레임 구조의 AAU 집합이다. AAU에는 압축된 오디오 데이터를 담고 있고, 이것을 풀어 PCM데이터를 만들어 낼 수 있는 정보를 담고 있다. 여기서 언급하는 오디오

댓글 0

조회수 2,165

등록된 댓글이 없습니다.

하드웨어HOME > 하드웨어 > 전체 목록

게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기