Botond Magyarosi
Botond Magyarosi

Reputation: 230

Writing AVAudioPCMBuffer into an AVAudioFile compressed

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

Answers (1)

Gordon Childs
Gordon Childs

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

Related Questions