Wav 웨이브 음악 파일의 PCM 데이터를 읽어 파형으로 출력하기 - 3 - Whitmem
Wav 웨이브 음악 파일의 PCM 데이터를 읽어 파형으로 출력하기 - 3
Sound Development
2024-09-04 13:14 게시 d43180c6df7cffaae725

0
0
90
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
이전 게시물 WAV 사운드 파일 로더 만들기 및 PCM Data 로드 - 2에서는 WAV 파일 클래스를 만들어보고 로드하는 부분까지 구현을 완료하였다. 한편 마지막 PCM 데이터를 로드하는 부분에 오류가 약간있는데, PCMData 의 버퍼 사이즈만큼 fileStream에서 읽어야 한다.
pcmData = new byte[dataSize]; bufferSize = fileStream.Read(pcmData, 0, pcmData.Length); fileStream.Close();
이렇게 PCM 스트림을 읽도록 구현하면 문제가 없을 것 이다.
PCM 데이터 double 형으로 변환
위 오디오 자료에서 알 수 있다시피, BitsPerSample 에서 비트 수는 16비트이다. 이는 하나의 샘플이 16비트로 구성되어 있다는 것인데, 16비트는 바이트 단위로 2바이트이다. 2바이트라는 공간 하나에 샘플 하나의 데이터가 기록되어있다는 것 이며, 이를 직접 읽어들여 double로 변환해야한다.
16비트는 Int16 비트로 볼 수 있으며, 다른 언어에서는 short 데이터 형으로 해독할 수 있다. short 데이터 형은 -32768~32767까지의 범위를 가지기에, 2바이트를 하나 읽여들여, int16 내지 short 형으로 변환한 뒤 32767 을 나누어줌으로써 약 -1...~1 범위로 이동할 수 있다.
오디오 PCM 데이터에는 한 샘플이 좌 우 채널 번갈아가면서 존재하기 때문에, 번갈아가면서 데이터를 읽어야 한다. 위 예시에서 첫 번째 2바이트는 left channel의 샘플 데이터이고, 두 번째 2 offset~ 2length 까지는 right channel의 샘플 데이터이다.
이를 for 문으로 나타내면 위와 같다.
double[] leftChannels = new double[stream.Length/4]; double[] rightChannels = new double[stream.Length / 4];
좌측 채널과 우측 채널은 2바이트당 하나의 샘플인데, 좌 우 채널 가각 동일한 길이의 샘플을 나타내야 하기 때문에, 2로 나눈 뒤 다시 채널 개수만큼 2로 나누면 총 4를 나눈 것 과 같다. stream은 2칸 단위로 건너뛰면서 for문을 시행하되, for의 진행 값인 i에 대해 4를 나누어서 나머지가 0이라면 각각 0, 4, 8, 12 오프셋임을 나타낸다. 이의 경우는 left channel을 의미하기에 leftchanel에 담아주고, 그 외는 right channel에 담아준다. 특히 left channel이 시작, right channel이 한 상의 끝이기 때문에 right channel을 넣어준 뒤 내부 Index는 1 더해주어 차곡 차곡 쌓이게끔 탑재한다.
for(int i=0;i<stream.Length; i+=2) { int value = BitConverter.ToInt16(stream, i); double realValue = ((double)value / (double)32767); if (i % 4 == 0) { leftChannels[internalIndex] = realValue; } else { rightChannels[internalIndex] = realValue; internalIndex += 1; } }
각각 두 개씩 가져와진 2 byte의 array 는 BitConverter 을 통해 Int16비트로 변환해준다. double 값에 넣어주기 위해 32767 로 나누어 double 형으로 변환한다. 이 떄 주의할 점은, value와 32767은 기본적으로 int 형이기 때문에 double로 우선 변환 뒤 나누어주어야 double형으로 계산이 가능하다.
그리기
다음으로는 화면상에 그리기 위해서, panel 컴포넌트를 하나 생성해준 뒤, 해당 panel에 대해 CreateGrpahics를 수행한다. Panel 을 2개 만든 이유는 하나는 leftChannel, 하나는 rightChannel을 표시하기 위함이다. 각각 초기화를 한 뒤, leftChannel 과 rightChannel을 for문을 돌면서 * 40 배율 해준 값을 화면상에 차곡 차곡 출력해준다. 선을 두개 이어야 하므로, 이전 선은 저장하고 이전 선과 새로운 선을 잇는다.한편 x 값은 /10 하며 화면상에 압축하여 표시할 수 있도록 한다.
실행 결과
이로써 화면상에 파형을 성공적으로 출력하였다. 다음에는 두 오디오 파일을 합성하는 방법에 대해서 알아보고자 한다.
댓글 0개
댓글은 일회용 패스워드가 발급되며 사이트 이용 약관에 동의로 간주됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.