PCM 이란?
PCM이란 Purse Code Modulation 의 약자로, 아날로그 신호를 디지털 신호로 변화시키는 방법 중 하나이다.
특히, 음성 음악 등 오디오 데이터를 디지털화 할 때 많이 사용된다. 아날로그 신호는 연속적 신호이며, 이를 디지털화하기 위해서는 특정한시간 간격으로 신호를 측정하는 샘플링 작업이 필요하고, 이를 일정한 비트 수로 표현하게 되는데 이 과정을 PCM 이라고한다.
주요 용어
1. 샘플링 (Sampling)
- 연속적인 아날로그 신호를 디지털로 변환하기 위해 일정한 시간 간격으로 신호 값을 측정하는 과정
- 샘플링 주파수란 초당 측정하는 샘플의 횟수
- 나이퀴스트 샘플링 이론에 따르면, 아날로그 신호를 완벽하게 재구성하려면 신호의 최대 주파수보다 최소 두 배 높은 주파수로 샘플링해야 함
2. 양자화 (Quantization)
- 샘플링된 값을 디지털 데이터로 변환하기 위해 연속적인 아날로그 값들을 이산적인 값들로 변환하는 과정
- 비트 깊이란, 위 과정에서 각 샘플을 몇 비트로 표현할 지 결정하는 것을 뜻함
- 양자화 과정에서 일부 정보가 손실될 수 있으며, 이를 양자화 잡음 이라고 함.
3. 부호화 (Encoding)
- 양자화된 값을 이진수로 변환하여 디지털 신호로 표현하는 과정
- 이 과정에서각 샘플이 부호화되어 0과 1로 구성된 뒤 디지털 데이터로 저장됨
PCM의 장단점
장점
- 비압축 방식 : PCM은 원본 아날로그 신호의 품질을 최대한 유지하는 비압축 방식으로, 손실 없이 높은 품질의 오디오 데이터를 유지할 수 있다.
- 표준화 : PCM은 다양한 디지털 오디오 형식의 기본 기술로 사용되며, 오디오CD, 전화 시스템 등 많은 산업 표준에서 사용된다.
단점
- 파일 크기 : 비압축 방식이기 때문에 데이터의 크기가 매우 큼
- 양자화 잡음 : 양자화 과정에서 원래 아날로그 신호가 디지털화되면서 약간의 정보 손실이 발생하는데, 이는 양자화 잡음으로 이어질 수 있고, 비트 깊이가 높을수록 잡음이 줄어든다.
주요 속성
1. 샘플링 주파수 : 아날로그 신호를 샘플링하는 속도
2. 비트 깊이 : 각 샘플이 몇 비트로 표현되는지를 나타냄
3. 채널 : 오디오 신호는 모노(1채널), 스테레오(2채널), 서라운드(다채널) 등 여러 채널로 구성될 수 있음
응용 분야
오디오, CD, VoIP(인터넷 전화), 방송 및 스튜디오 레코딩, 안드로이드 및 모바일 기기
데이터 처리 방법
PCM에서 데이터를 처리하려면 샘플링 주파수와 비트 깊이 등의 속성을 고려해야하며, 안드로이드와 같은 환경에서는 PCM 데이터를 실시간으로 수신하거나, 스트리밍하여 오디오로 변환하는 작업을 수행할 수 있다.
예를 들어, 네트워크를 통해 수신한 PCM 데이터를 바로 재생하는 것이 가능하다.
개발 관련 용어
1. DAC (Digital-to-Analog Converter) : 디지털로 저장된 PCM 데이터를 아날로그 신호로 변환하여 스피커 등에서 재생할 때 사용
2. ADC (Analog-to-Digital Converter) : 아날로그 신호를 디지털 신호로 변환할 때 사용되며, PCM 데이터를 생성하는 데 핵심적인 역할을 한다.
3. Linear PCM : 일반적으로 언급되는 PCM은 선형 PCM (Linear PCM 또는 LPCM)으로, 이는 양자화된 값들이 선형적으로 표현된다는 의미이다.
안드로이드에서의 활용
주로 오디오 처리와 관련된 작업에서 사용하며, PCM은 오디오 데이터를 비압축된 상태로 처리할 수 있는가장 기본적인 형식이기 때문에, 실시간 오디오 스트리밍, 녹음, 재생, 그리고 오디오 처리 작업 등에 많이 사용되고, 주로 AudioTrack API를 이용한다.
PCM 재생 기본 예제 코드
// 샘플링 주파수, 채널 설정 및 PCM 데이터 형식 설정
int sampleRate = 44100; // 44.1kHz
int channelConfig = AudioFormat.CHANNEL_OUT_MONO; // 모노
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 16비트 PCM 데이터
// AudioTrack을 사용하여 PCM 데이터를 재생
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC, // 스트림 타입
sampleRate, // 샘플링 주파수
channelConfig, // 채널 설정
audioFormat, // PCM 데이터 형식
AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat), // 버퍼 크기
AudioTrack.MODE_STREAM // 스트리밍 모드
);
// PCM 데이터 재생
audioTrack.play();
audioTrack.write(pcmData, 0, pcmData.length); // pcmData는 PCM 오디오 데이터
AudioTrack을 사용하여 네트워크 스트리밍으로 수신한 PCM 데이터를 실시간으로 재생할 수 있고, 게임이나 VoIP(인터넷 전화) 애플리케이션에서 실시간 음성 재생 등 다양한 오디오 관련 작업에 적합하다.
AudioRecord를 이용한 PCM 데이터 녹음
안드로이드에서는 AudioRecord 클래스를 사용하여 PCM 데이터를 녹음할 수 있다. 이는 사용자의 마이크 입력을 디지털 PCM 데이터로 변환하여 저장하거나 네트워크로 전송할 때 유용하다.
// 샘플링 주파수, 채널 설정 및 PCM 데이터 형식 설정
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO; // 모노
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 16비트 PCM 데이터
int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
// AudioRecord 초기화
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, // 마이크 입력
sampleRate, // 샘플링 주파수
channelConfig, // 채널 설정
audioFormat, // PCM 데이터 형식
bufferSize // 버퍼 크기
);
// 녹음 시작
audioRecord.startRecording();
// PCM 데이터를 버퍼에 녹음
byte[] buffer = new byte[bufferSize];
int bytesRead = audioRecord.read(buffer, 0, buffer.length);
// 녹음 종료
audioRecord.stop();
audioRecord.release();
위 코드는 마이크 입력은 16비트 PCM데이터로 녹음하고, 이를 실시간으로 처리하거나 파일로 저장하는 코드이다.
해당 방법은 음성 인식, VoIP, 오디오 분석 앱에서 자주 사용된다.
네트워크 스트리밍을 통한 PCM 데이터 전송
// 서버와의 연결 설정
Socket socket = new Socket("server_address", serverPort);
OutputStream outputStream = socket.getOutputStream();
// PCM 데이터를 서버로 전송
outputStream.write(pcmData, 0, pcmData.length);
// 연결 종료
outputStream.close();
socket.close();
위 코드는 실시간 PCM 데이터를 서버로 전송하는 기본적인 TCP 소켓 연결 예제이다. VoIP 애플리케이션이나 실시간 오디오 스트리밍에서 PCM 데이터를 실시간으로 전송하는 데 자주 사용된다.
PCM 파일 재생 및 저장
PCM 데이터를 파일로 저장하거나 파일에서 읽어와 재생할 수 있다. PCM 데이터는 WAV 형식과 같은 파일 형식으로 저장될 수 있고, WAV 파일의 헤더를 제외한 데이터 부분은 사실상 PCM 데이터이다.
저장
// PCM 데이터를 파일로 저장
FileOutputStream fos = new FileOutputStream(new File("output.pcm"));
fos.write(pcmData);
fos.close();
재생
// PCM 파일에서 데이터 읽기
FileInputStream fis = new FileInputStream(new File("input.pcm"));
byte[] buffer = new byte[bufferSize];
int bytesRead = fis.read(buffer);
// AudioTrack을 통해 PCM 데이터 재생
audioTrack.play();
audioTrack.write(buffer, 0, bytesRead);
fis.close();
위 방법은 오디오를 녹음 후에 저장하거나, 저장된 PCM 데이터를 다시 재생할 때 유용하다.
오디오 이펙트 및 실시간 처리
안드로이드에서는 PCM 데이터를 실시간으로 처리하여 다양한 오디오 효과를 적용할 수 있다.
예를 들어, 이퀄라이저, 에코, 노이즈 감소 등의 효과를 추가할 수 있다.
PCM은 비압축된 상태이므로, 각 샘플을 수학적으로 조작하여 효과를 추가할 수 있다.
// 간단한 PCM 데이터 증폭 예제
for (int i = 0; i < pcmData.length; i++) {
pcmData[i] = (byte)(pcmData[i] * 2); // 볼륨을 2배로 증폭
}
audioTrack.write(pcmData, 0, pcmData.length);
결론
이외에도, OpenSL ES를 이용한 고성능 오디오 처리(더 낮은 레벨의 오디오 하드웨어 접근을 가능하게 하여 성능 향상)도 가능하며, 안드로이드에서 PCM 데이터는 오디오 처리 작업에 필수적인 역할을 한다.
AudioTrack과 AudioRecord와 같은 기본 API를 사용하여 PCM 데이터를 녹음하거나 재생할 수 있고, 네트워크 스트리밍, 실시간 오디오 처리, 파일 저장 등 다양한 방식으로 응용할 수 있고, OpenSL ES를 통해 더 고성능의 오디오 처리를 구현할 수 있다.
'Android' 카테고리의 다른 글
Hilt (의존성 주입) (1) (2) | 2024.09.18 |
---|---|
Wear Os (워치) (4) | 2024.09.17 |
WebRTC (1) - 웹RTC (스트리밍) (1) | 2024.09.08 |
Glide 글라이드 (이미지) (2) | 2024.09.07 |
BaseRecyclerView (리사이클러 뷰) (0) | 2024.07.26 |