AVAudioFile.length is 0, even if the file exists

I am creating an AVAudioFile to record sound in an audio file. If the file already exists, I want to move framePosition to the end of the file to continue writing at the end instead of replacing the existing file.

I did some tests trying to read the buffer from a file to a new file with a different URL so that it would not overwrite the original file. I get a crash when I try to read the buffer into a new file:

let audioFile = try AVAudioFile(forReading: [URL to existing .caf file]) let audioFrameCount = AVAudioFrameCount(UInt32(audioFile.length)) let audioBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: audioFrameCount) let newAudioFile = try AVAudioFile(forWriting: [another URL], settings: self.engine.mainMixerNode.outputFormatForBus(0).settings) try newAudioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!) <-- CRASHES ON THIS LINE 

Crash log: application terminated due to an uncaught exception "com.apple.coreaudio.avfaudio", reason: "error -50"

Man, I really hate CoreAudio crash logs. They donโ€™t tell me anything!

Is it impossible to read the data in the file that was created for writing?

UPDATE

OK, so after some suggestions I made some changes. Basically, these are the steps that I take:

  • Check if the file exists.
  • If so, open it for reading and get a sound buffer.
  • Create a new file for writing (using the same file URL)
  • Use writeFromBuffer to write buffer from old file to new file
  • Move the framePosition of the new file to the end so I can continue recording / writing to it.

However, the length of the new file is 0 after I wrote it.

Here is my code:

 //Check if a file already exists. If so continue to record at the end of it var audioBuffer : AVAudioPCMBuffer! var audioFrameCount : AVAudioFrameCount! if (NSFileManager.defaultManager().fileExistsAtPath(self.audioRecordURL.path!)) { do { let existingAudioFile = try AVAudioFile(forReading: self.audioRecordURL) audioFrameCount = AVAudioFrameCount(existingAudioFile.length) if (audioFrameCount > 0) { audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount) } } catch let error as NSError { NSLog("Error reading buffer from file %@", error.localizedDescription) } } //Create a new file. This will replace the old file do { self.audioFile = try AVAudioFile(forWriting: self.audioRecordURL, settings: self.engine.mainMixerNode.outputFormatForBus(0).settings) } catch let error as NSError { NSLog("Error creating AVAudioFile %@", error.localizedDescription) } //Read the audio buffer from the old file into the new file if (audioBuffer != nil) { do { try self.audioFile.writeFromBuffer(audioBuffer) self.audioFile.framePosition = self.audioFile.length } catch let error as NSError { NSLog("Error reading buffer into file %@", error.localizedDescription) } } 

By the way, the name readIntoBuffer is very confusing to me. It seems you should use this method to read the file into the buffer, but according to the documentation you should use it to read the buffer into the file? So why can't I use this method to add a buffer to my file? Why should I use writeFromBuffer?

UPDATE 2

So, I managed to solve it. Apparently, I had to call readIntoBuffer to actually fill the buffer with data before I could use it. So I added this line

 try existingAudioFile.readIntoBuffer(audioBuffer) 

after

 audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount) 
+5
source share
1 answer

I'm not sure that this is just a typo in the code that you indicated here, and I'm not an expert in this area, but, presumably, you were dealing with the fact that an accident occurred:

 try audioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!) 

because it is reasonable that you cannot read from a file open for writing (newAudioFile).

And after filling this buffer, you want to write to a new file using writeFromBuffer https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioFile_Class/#//apple_ref/occ/instm/AVAudioFile/writeFromBuffer:error :

+1
source

Source: https://habr.com/ru/post/1237531/


All Articles