이전 챕터에서는 AudioRecord를 통한 PCM 데이터 캡처 및 저장 방법을 학습했습니다. 본 챕터에서는 AudioTrack의 기능을 활용하여 저장된 PCM 데이터를 재생하는 방법을 탐구합니다.
AudioTrack 기본 개념 AudioTrack 클래스는 자바 애플리케이션의 단일 오디오 리소스를 관리하고 재생하는 역할을 합니다. 이는 PCM 오디오 버퍼를 오디오 수신기로 스트리밍하는 데 사용되며, write(byte[], int, int), write(short[], int, int), write(float[], int, int, int) 메서드를 통해 데이터를 전달합니다. AudioTrack 인스턴스는 정적 모드와 스트리밍 모드 두 가지 방식으로 작동합니다.
정적 모드 데이터를 한 번에 수신기에 전달하는 방식으로, 간단하고 효율적이지만 대용량 음성 재생에는 부적합합니다. 주로 소리 알림이나 시스템 경고음과 같은 메모리가 제한된 시나리오에 사용됩니다. 스트리밍 모드 네트워크 영상 재생과 유사하게 데이터를 지속적으로 전달합니다. 음성 파일 크기, 고해상도 오디오, 실시간 생성 데이터 등 다양한 상황에 적용 가능하지만, 자바 레이어와 네이티브 레이어 간 상호작용으로 인해 성능 손실이 발생할 수 있습니다.
AudioTrack API 핵심 메서드 getMinBufferSize() 메서드는 버퍼 크기를 계산하지만, 이 값은 실제 재생 시 조건에 따라 달라질 수 있습니다. 예를 들어, 동적 샘플링 레이트를 적용할 경우 최대 예상 샘플링 레이트에 맞춰 버퍼 크기를 조정해야 합니다.
구성 매개변수 설명
- streamType: Android의 AudioManager와 연동되어 장치의 오디오 관리 전략을 결정합니다.
- channelConfig: MONO(단채널) 또는 STEREO(이채널) 설정 가능
- audioFormat: PCM 16비트 등 지원되는 포맷 지정
AudioTrack 초기화 예시
public void initializeAudioTrack() {
int bufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
AudioAttributes attrs = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build();
AudioFormat format = new AudioFormat.Builder()
.setSampleRate(44100)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build();
audioTrack = new AudioTrack(attrs, format, bufferSize, AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE);
} else {
audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM
);
}
}
데이터 재생 로직
public void startPlayback() {
try {
FileInputStream inputStream = new FileInputStream("audio_data.pcm");
byte[] buffer = new byte[bufferSize];
audioTrack.play();
while (isPlaying) {
int bytesRead = inputStream.read(buffer);
if (bytesRead == -1) break;
audioTrack.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
자원 해제 프로세스
public void releaseResources() {
if (audioTrack != null) {
audioTrack.stop();
audioTrack.release();
audioTrack = null;
}
// 추가 리소스 정리 코드
}
이러한 구조를 통해 PCM 형식의 오디오 데이터를 효과적으로 재생할 수 있습니다. 다음 챕터에서는 카메라 API를 활용한 비디오 캡처 기법을 탐구할 예정입니다.