시작
제가 조사한 바에 따르면 안드로이드로 오디오를 녹음하는 방법에는 세 가지가 있습니다. 첫 번째는 MediaRecorder를 이용하는 것이며 두 번째는 AudioRecord를 마지막은 Native AudioRecord를 사용하여 녹음을 할 수 있습니다.
각 각의 API 마다 장점이 있지만 그 중 AudioRecord에 대해 정리한 글이며 Andriod Developer의 AudioRecord 페이지를 번역한 게시물입니다. 오역이 있을 수 있으니 원문이 필요하신 분들은 아래 링크를 이용해 주세요.
AudioRecord | Android Developers
developer.android.com
AudioRecord란?
AudioRecord는 Object 클래스를 상속 받고 있으며 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 함수는 오디오 데이터를 읽기 위해 쓰이는 함수며 세 가지 방법이 존재합니다.
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: 요청한 바이트의 수. |
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 |