I want to record audio on iOS in real time, analyze the raw audio data and save parts of the recorded data. I'm recording the data with this code: https://gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107
Now, my data is saved in a Float array and I want to save it to an audio file. I tried doing it with this code:
let fileMgr = FileManager.default
let dirPaths = fileMgr.urls(for: .documentDirectory, in: .userDomainMask)
let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
AVEncoderBitRateKey: 16,
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100] as [String: Any]
let soundFileUrl = dirPaths[0].appendingPathComponent("recording-" + getDate() + ".pcm")
do {
let audioFile = try AVAudioFile(forWriting: soundFileUrl, settings: recordSettings)
let format = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 44100, channels: 2, interleaved: true)
let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 3000)
for i in 0..<circBuffer.count {
audioFileBuffer.int16ChannelData?.pointee[i] = Int16(circBuffer[i])
}
try audioFile.write(from: audioFileBuffer)
}
On the last line, I get an error which says:
ERROR: >avae> AVAudioFile.mm:306: -[AVAudioFile writeFromBuffer:error:]: error -50 amplitudeDemo(79264,0x70000f7cb000) malloc: * error for object 0x7fc5b9057e00: incorrect checksum for freed object - object was probably modified after being freed. * set a breakpoint in malloc_error_break to debug
I already searched in a lot of other questions, but I couldn't find anything that helped me.
In your code at this line:
You declare an
AVAudioPCMBuffer
with capacity 3000 frames * 2 channels, which means the allocated buffer for youraudioFileBuffer
can contain 6000 samples. If the index for the channel data exceeds this limit, your code destroys the nearby regions in the heap, which causes object was probably modified error.So, your
circBuffer.count
may probably be exceeding this limit. You need to allocate enough buffer size, for theAVAudioPCMBuffer
.Some notes added as comments, please check them before trying this code.
UPDATE Sorry, for showing untested code, two things fixed:
commonFormat:
when instantiatingAVAudioFile
.int16ChannelData
(and other channel data) does not return expected pointers as described in its documentation when interleaved, data filling loop modified to fit for the actual behaviour.Please try.