C++, C# 등 프로그램 개발 시 wav 파일 PCM 파형 데이터를 불러오기 1 - Whitmem
C++, C# 등 프로그램 개발 시 wav 파일 PCM 파형 데이터를 불러오기 1
Sound Development
2023-01-07 06:38 게시 9b3207a9f784342377ee

1
0
251
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
C++에서 DirectX 를 통해 게임을 개발하다 보면, DirectSound 부분을 구현하면서, 음악을 직접 재생해야하는 경우가 있습니다.이외에도 C# 등에서, 자바등에서 wav 파일을 편집하거나 자르거나, 또는 파형을 로드할 때 직접 wav를 로드하곤 합니다.
라이브러리를 찾아서 쓰기엔 좀 그렇고, 직접 오디오 파일의 구조를 알면 좋기도 하기에 오디오 파일에 대한 구조나 구성 사항에 대해 알아볼 필요가 있죠,
이 게시물에서는 wav 파일에 대해 헤더가 아닌, PCM 데이터를 파형 데이터로 가져오는 방법에 대해 자세히 서술합니다.
WAV 파일을 사용하는 이유
기본적인 wav 파일 형식은 비교적 용량이 크다는 특징이 존재합니다.
이는 즉 압축되지 않는 포맷이라는 것이고, 프로그래밍을 할 때 별도 압축 해제 작업을 해줄 필요 없이 바로 가져와 처리를 해주면 된다는 장점이 존재합니다.
물론 wav 라고 해서, 다 같은 wav 포맷이 아니라, 내부 컨테이너가 해서 따로 WAVE 형태인지, 다른 형태인지 등... 구성 사항이 나뉘는 것 같긴 하나, 기본적으로 우리가 오디오 편집 프로그램에서 wav PCM 16 bit로 저장하는 건 PCM 데이터가 들어가는 오디오 파일입니다. 여기서 언급하는 wav는 WAVE 형태인 16bit - PCM 데이터가 들어가는 오디오 PCM 데이터로 간주하겠습니다.
WAV 재생하기
기본적으로 wav 파일은 헤더 부분데이터 부분이 존재 합니다.
헤더 부분에는 오디오 파일의 크기에 대한 정보들, 데이터 부분에는 raw 데이터인 PCM 데이터가 담겨 있습니다.
raw 데이터는 소리 신호를 의미하는 데이터이기에 RAW 데이터만으로도 소리를 재생할 수 있지만,
소리 파일이 어느 크기로 구성되어 있는지, 얼마만큼 세분화되어 있는지 알 수 없기에 정확하게 의도한대로 재생할 수 없다는 문제가 발생합니다.즉, 헤더 없이 재생을 하더라도, 원본에서 의도한대로 재생하기 위해서는 재생 속도, 샘플링 크기 등을 알아야 합니다.

기본적으로 wav 파일의 header에서 다음과 같은 자료를 알아낼 수 있습니다.
ChannelSampleRateBitsPerSample...
지금 당장은 모든 헤더를 알 필요가 없습니다. 이 3가지 데이터를 통해 약간 곱해주고 나누어주면 다른 값도 얻을 수 있기에... 이 세가지 값이 중요합니다.
Channel 값
채널은 말 그대로, 오디오의 채널 수 입니다. 우리가 흔히 사용하는 스피커는 좌 우로 2개가 있습니다. 오디오 파일들도 이 좌 우 두대로 트랙을 나누어 놨는데, 이를 \"스테레오\"라고 합니다. 가끔 \"모노\"라고 하는 경우도 있는데, 이는 1 채널을 의미 합니다.

스테레오 채널 (위 : 좌 트랙, 아래 : 우 트랙)
스테레오의 경우 좌우 파형이 같아 보이지만, 미세하게 다릅니다. 그렇기에 실제 스피커로 들을 때 공간적인 느낌이 모노에 비해서 더 살아 있습니다. 헤드셋으로 모노로만 구성된 음악, 스테레오로 구성된 음악들을 들어보시면 확연하게 차이를 느낄 수 있을겁니다.
SampleRate 값
SampleRate는 초당 소리 샘플이 재생되는 속도를 의미 합니다. 여기서 샘플이라는 말이 나오는데, 샘플은 소리의 최소 단위라고 생각하면 될 것 같습니다. 즉 이 최소 단위인 샘플을 얼마나 빠른 속도로 읽어들일 것 인지에 대한 정보이지요. 이게 무슨 소리냐... 더 쉬운 설명을 위해 소리가 아니라, 글자로 예를 들어보겠습니다.
가나다라마바사아자차카파타
위 글자 데이터가 있습니다. 이를 1채널 소리 데이터라고 가정하겠습니다.

사람이 직접 글자를 읽는다고 할 때, 초당 2개의 글자를 읽는다고 하면, SampleRate는 2가 되는 것 입니다.
2hz가 되는 것이지요.

다시 소리로 돌아와,말이 빨라지면, 단위 시간당 파형 주기가 짧아지기에 SampleRate가 클수록(빠를 수록) 높은 소리가 납니다. (Pitch Shift)
말이 느려지면, 단위 시간당 파형 주기가 길어지기에 SampleRate가 작을수록(느릴 수록) 낮은 소리가 납니다.


위 이미지는 Audacity 소프트웨어에서 오디오 편집을 할 때 볼 수 있는 프로젝트 속도란 입니다.
입력 상자에 44100으로 작성되어 있는데, wav 의 기본적인 프로젝트들은 대부분 44100hz 로 구성 되어 있습니다. (44.1khz)

기본적으로 위 2개의 내용만 알면 그냥 PCM 데이터의 파형 부분은 끝났습니다. 더 이상 볼게 없습니다. 그런데 이러한 파형 데이터들은 결국 파형 자체로 저장되는 것이 아니라, bytes 단위 즉 비트(8비트=1바이트)로 저장됩니다.
그렇기에 이러한 샘플들이 결국 몇 사이즈 바이트로 저장되어 관리 되는지 알아야, 다시 몇 사이즈 바이트를 가져와 파형으로 바꿔줄 수 있습니다.
이에 대한 정보가 BitsPerSample 입니다.
BitsPerSample 값
말 그대로, Sample 당 Bits 개수 입니다. 여기서 8을 나눠주면 Bytes가 됩니다.(1바이트=8bits)
그럼 위 정보들을 바탕으로...

wav 파일의 대한 크기도 대략 계산해 낼 수 있겠지요?
ChannelSampleRateBitsPerSample

1채널 \"모노\", 44100hz SampleRate, BitsPerSample 16, 16bit-PCM, 6.7 초 짜리 wav PCM 데이터의 경우

총 샘플 개수 : 1 * 44100 * 6.7
총 차지 바이트 : 1 * 44100 * 6.7 * 16(BitsPerSample) / 8
PCM 데이터 가져오기
그럼 이제, 파형을 가져오는 방법에 대해 알아보겠습니다.
기본적으로 Data 부분에는 Raw PCM이 저장되어 있다고 언급했습니다. 이 Raw PCM 은 파형에 대한 16bit-PCM 정보를 글자로 바로 담은게 아니라, bytes로 변환되어 담겨 있습니다. (파일 구조 및 바이너리 작업을 해보셨다면 무슨말인지 이해하실 겁니다.) 즉, 16bit-PCM 으로 저장이 되어 있다는건, 각 샘플이 16bit(2bytes)로 저장되어 있다는 겁니다.

0 샘플 소리 데이터 2bytes 1 샘플 소리 데이터 2bytes 2 샘플 소리 데이터 3bytes

위 표는 모노 기준 샘플이 저장되는 순서 입니다.

스테레오의 경우 각 채널을 순서대로 번갈아가면서 저장되어 있습니다.
0 샘플 소리 데이터 LEFT 2bytes 0 샘플 소리 데이터 RIGHT 2bytes 1 샘플 소리 데이터 LEFT 3bytes ...

실제 소리는 초당 44100개의 샘플(44100hz)로 구성된 경우가 많으니, 샘플 개수가 몇 만~ 몇 십, 백 만개씩 되겠지요.

결국 16bit(2bytes)는 C# 기준 short 데이터 형(Int16)
2바이트씩 읽어줘서 Int16으로 변환하면 최대 -32768~32767 값의 범위로 나옵니다.
이를 다시 Normalize, 노말화하기 위해 32767 정도로 나누어주고, 각 끝 값이 초과하는 건 잘라주면, -1~+1 값으로 나오겠지요. 이를 그래프로 그려주면 됩니다.
댓글 0개
댓글은 일회용 패스워드가 발급되며 사이트 이용 약관에 동의로 간주됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.