본문 바로가기
개발/Android

AudioRecord 소개

by 준그래머 2023. 7. 20.
반응형

시작

제가 조사한 바에 따르면 안드로이드로 오디오를 녹음하는 방법에는 세 가지가 있습니다. 첫 번째는 MediaRecorder를 이용하는 것이며 두 번째는 AudioRecord를 마지막은 Native AudioRecord를 사용하여 녹음을 할 수 있습니다.

 

각 각의 API 마다 장점이 있지만 그 중 AudioRecord에 대해 정리한 글이며 Andriod DeveloperAudioRecord 페이지를 번역한 게시물입니다. 오역이 있을 수 있으니 원문이 필요하신 분들은 아래 링크를 이용해 주세요.

 

AudioRecord  |  Android Developers

 

developer.android.com

AudioRecord란?

AudioRecordObject 클래스를 상속 받고 있으며 AudioRouting, MicrophoneDirection, AudioRecordingMonitor 들을 구현하고 있습니다.

 

AudioRecord 클래스는 플랫폼의 오디오 입력 하드웨어에서 Java 응용프로그램이 오디오를 녹음할 수 있도록 오디오 자원을 관리합니다. 이것은 AudioRecord 객체에서 데이터를 “pulling” (읽기)를 통해 수행됩니다. 응용 프로그램은 read(byte[], int, int), read(short[], int, int) 또는 read(java.nio.ByteBuffer, int) 중 한 가지 방법을 사용하여 AudioRecord 객체를 정확하게 polling 합니다. 위 세 가지 방법 중 AudioRecord를 사용하는 유저가 가장 편리하다고 생각되는 오디오 데이터 저장 방식에 맞춰 사용하면 됩니다.

 

AudioRecord 객체를 생성 할 때, 객체는 새 오디오 데이터를 채울 오디오 버퍼를 초기화 시킵니다. 생성 중에 지정된 이 버퍼의 사이즈는 데이터를 읽기 전에 얼마나 녹음할 수 있는지 시간을 결정합니다. 데이터는 하드웨어에서 전체 녹음 버퍼 사이즈의 하위 단위인 chunk 사이즈로 읽어야 합니다.

 

AudioRecord 인스턴스를 생성하는 프로그램은 Manifest.permission.RECORD_AUDIO 권한 또는 UnsupportedOperationException 예외처리가 필요합니다. 만약 예외처리가 되지 않으면 빌더가 build() 도중에 STATE_UNINITIALIZED 상태의 인스턴스를 반환할 것입니다.

 

AudioRecord의 함수

모든 함수를 정리할 수 없어 자주 쓰이는 함수에 대해 정리해봤습니다.

생성자

AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, 
                int audioFormat, int bufferSizeInBytes)
Parameters Description
audioSource int: 오디오 데이터를 입력 받을 장치, MediaRecorder.AudioSource 를 참조
sampleRateInHz int: 헤르츠 단위의 샘플 비율. 44100Hz는 현재 모든 장치에서 작동이 보장되는 유일한 속도이지만 22050, 16000 및 11025와 같은 다른 속도는 일부 장치에서 작동할 수 있습니다. AudioFormat#SAMPLE_RATE_UNSPECTED는 일반적으로 소스의 샘플링 속도인 경로 종속 값을 사용하는 것을 의미합니다. #getSampleRate()를 사용하여 선택한 실제 샘플링 속도를 검색할 수 있습니다.
channelConfig int: 오디오 채널 구성을 설명 AudioFormat#CHANNEL_IN_MONO 과 AudioFormat#CHANNEL_IN_STEREO 를 확인
audioFormat int: 오디오 데이터가 표시될 형식  AudioFormat#ENCODING_PCM_8BIT, AudioFormat#ENCODING_PCM_16BIT, AudioFormat#ENCODING_PCM_FLOAT
bufferSizeInBytes 녹음 중 오디오 데이터가 기록되는 버퍼의 총 크기(바이트)입니다. 이 크기보다 작은 chunk 로 이 버퍼에서 새 오디오 데이터를 읽을 수 있습니다. AudioRecord 인스턴스를 성공적으로 만들기 위해 필요한 최소 버퍼 크기를 결정하려면 #getMinBufferSize(int, int, int)를 참조하십시오. getMinBufferSize()보다 작은 값을 사용하면 초기화에 실패합니다.

 

read 함수

read 함수는 오디오 데이터를 읽기 위해 쓰이는 함수며 세 가지 방법이 존재합니다.

 

1. read(byte[], int, int)

public int read (byte[] audioData,
                int offsetInBytes,
                int sizeInBytes)

이 함수는 오디오 하드웨어에서 오디오 데이터를 읽어 byte 배열로 기록합니다. AudioRecord 생성자에 의해 지정된 포맷은 배열 데이터에 해당하는 ENCODING_PCM_8BIT 형식이여야 합니다.

Parameters Description
audioData byte: 녹음된 데이터가 기록된 배열. 이 값은 null일 수 없습니다.
offsetInBytes int: byte 단위로 기록된 데이터에서 audioData 안의 인덱스
sizeInBytes int: 요청한 바이트의 수.

 

2. read(short[], int, int)

public int read (short[] audioData,
                int offsetInShorts,
                int sizeInShorts)

이 함수는 오디오 하드웨어에서 오디오 데이터를 읽어 short 배열로 기록합니다. AudioRecord 생성자에 의해 지정된 포맷은 배열 데이터에 해당하는 ENCODING_PCM_16BIT 형식이여야 합니다.

Parameters  
audioData short: 녹음된 데이터가 기록된 배열. 이 값은 null일 수 없습니다.
offsetInShorts int: short 단위로 기록된 데이터에서 audioData 안의 인덱스. 데이터에 접근이 배열의 범위를 벗어나는 것을 야기하기 때문에 음수 일 수 없습니다.
sizeInShorts int: 요청된 shor의 수. 데이터에 접근이 배열의 범위를 벗어나는 것을 야기하기 때문에 음수 일 수 없습니다.

 

3. read(java.nio.ByteBuffer, int)

public int read (ByteBuffer audioBuffer,
                int sizeInBytes)

direct buffer로 기록하기 위해 오디오 하드웨어에서 오디오 데이터를 읽습니다. 만약 이 버퍼가 direct buffer가 아닌 경우 이 함수는 항상 0을 반환합니다. 이 값은 Buffer.position() 에 의해 반환되며 이 함수를 호출한 뒤에도 값은 변하지 않습니다. 버퍼의 데이터 표현은 AudioRecord의 생성자에 명시된 포맷에 따라 달라지며 기본 endian이 됩니다.

 

반환되는 int 값의 종류는 read 함수 모두 동일합니다.

Returns  
int 0 또는 읽은 바이트의 양의 수 또는 error code 들 중 한 가지 수.
바이트의 수는 sizeInBytes를 초과할 수 없으며 프레임 사이즈의 배수가 되도록 잘립니다.

error code
• ERROR_INVALID_OPERATION 객체가 제대로 초기화 되지 않는 경우
• ERROR_BAD_VALUE 파라미터가 유효한 데이터 및 인덱스로 되어 있지 않는 경우
• ERROR_DEAD_OBJECT 객체가 더 이상 유효하지 않고 재 생성이 필요한 경우. 만약 몇 몇 데이터 성공적으로 전송된 경우 죽은 객체의 이 에러코드는 반환되지 않습니다. 이 경우 다음 번 read() 호출 시에 반환됩니다.
• ERROR 다른 에러가 있는 경우

 

getMinBufferSize 함수

getMinBufferSize(int, int, int)

public static int getMinBufferSize (int sampleRateInHz, 
                int channelConfig, 
                int audioFormat)

AudioRecord 객체를 성공적으로 생성하기 위해 필요한 최소 버퍼 사이즈를 바이트 단위로 반환해줍니다. 이 사이즈는 로드 시에 부드러운 녹음을 보장하지 않으며, 새 데이터에 대해 AudioRecord 인스턴스가 polling 예상 빈도에 따라 그 값을 더 높게 선택해야 합니다. 구성 값에 대한 보다 유용한 정보는 AudioRecord(int, int, int, int, int)를 확인하십시오.

 

Parameters  
sampleRateInHz int: 헤르츠로 표시된 샘플 비율
   AudioFormat#SAMPLE_RATE_UNSPECIFIED 은 사용 불가 
channelConfig int: 오디오 채널 구성을 설명
   AudioFormat#CHANNEL_IN_MONO 과
   AudioFormat#CHANNEL_IN_STEREO 를 확인
audioFormat int: 오디오 데이터가 표시될 형식 
   AudioFormat#ENCODING_PCM_16BIT 를 확인

 

Returns  
int ERROR_BAD_VALUE 녹음 파라미터가 하드웨어에 의해 지원되지 않은 경우, 유효하지 않은 값이 전달 된 경우, 
ERROR 구현이 하드웨의 입력 속성 또는 바이트 단위의 최소 버퍼 사이즈를 쿼리할 수 없는 경우 

 

결론

AudioRecord는 byte 단위의 오디오 데이터를 관리할 수 있습니다. 이게 장점이자 단점인데, 이 데이터를 이용하면 사용자에게 다양한 기능을 제공할 수 있지만 이것 때문에 오디오에 대한 지식이 필요하고 MediaRecoder에 비해 구현이 힘들다고 할 수 있습니다.

 

 

 

 

 

반응형

'개발 > Android' 카테고리의 다른 글

내가 만들어본 KoreanNumberFormatter 라이브러리  (0) 2023.07.20
AudioRecord를 이용해 PCM 파일로 녹음해보기  (0) 2023.07.20
WorkManager 및 Kotlin  (0) 2023.07.19
WorkManager 기초  (0) 2023.07.19
WorkManager 소개  (0) 2023.07.19