Reputation: 230
We're working on an application which records and persists microphone input. The use of AVAudioRecorder
was not an option, because real-time audio processing is needed.
AVAudioEngine
is used because it provides low-level access to the input audio.
let audioEngine = AVAudioEngine()
let inputNode = audioEngine.inputNode
let inputFormat = inputNode.inputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount(inputFormat.sampleRate * sampleInterval), format: inputFormat) { (buffer: AVAudioPCMBuffer, time: AVAudioTime) -> Void in
// sound preprocessing
// writing to audio file
audioFile.write(buffer.floatChannelData![0])
})
Our issue is that the recording is quite large. For a 5 hour recording, the output audio file is 1.2GB with .caf
format.
let audioFile = AVAudioFile(forWriting: recordingPath, settings: [:], commonFormat: .pcmFormatFloat32, interleaved: isInterleaved)
Is there a nice way to compress the audio file writing to it?
The default sampling frequency is 44100Hz. We will use AVAudioMixerNode to downsample the input to 20Khz (lower quality is acceptable in our case) but the size of the output won't be acceptable in size.
The recording contains large segments of background noise.
Any suggestions?
Upvotes: 7
Views: 6261
Reputation: 36074
The .caf
container format supports AAC compression. Enable it by setting the AVAudioFile
settings dictionary to [AVFormatIDKey: kAudioFormatMPEG4AAC]
:
let audioFile = try! AVAudioFile(forWriting: recordingPath, settings: [AVFormatIDKey: kAudioFormatMPEG4AAC], commonFormat: .pcmFormatFloat32, interleaved: isInterleaved)
There are other settings keys that influence the file size and quality: AVSampleRateKey
, AVEncoderBitRateKey
and AVEncoderAudioQualityKey
.
p.s. you need to close your .caf
file when you've finished with it. AVAudioFile
doesn't have an explicit close()
method, so you close it implicitly by nilling any references to it. Uncompressed .caf
files seem to be playable without this, but AAC files are not.
p.p.s as of 2024 AVAudioFile
has an explicit close()
method (iOS 18+ and macOS 18+). Exciting times.
Upvotes: 13