iosswiftavaudiorecorder

Swift File.read(into: ) throws "Foundation._GenericObjCError error 0" error


Im working on a project that consists of recording a watermelon thump and predict its sweetness by the sound it produces. Im using AVAudioRecorder to record and save the audio. but when I try to open and read the file it gives me an error (This error only occurs when I test the app on my actual iPhone Xr but not when I use the xcode simulator) the error code is:

"Foundation._GenericObjCError error 0" .

Here is the recording function and fetching audios function:

private func startRecording() {
        do {
            
            if self.record{
                // recording already started
                
                recorder.stop()
                self.record.toggle()
                // updating data for every recording
                self.getAudios()
                return
            }
            // record audio
            
            // store audio in document directory
//            var highPassFilter = AVAudioUnitEQFilterType.highPass
//            var lowPassFilter = AVAudioUnitEQFilterType.lowPass
            
            let fileURL: URL = {
                        let src = "thump.wav"
                        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(src)
                   }()
            
//            let fileURL : URL = {
//                return Bundle.main.url(forResource: "thump", withExtension: "wav")
//            }()!
            
            let recordSettings: [String : Any] = [AVFormatIDKey: Int(kAudioFormatLinearPCM),
                                                  AVSampleRateKey: 44100.0,
                                                  AVNumberOfChannelsKey: 1,
                                                  AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue ]
            
            self.recorder = try AVAudioRecorder(url: fileURL, settings: recordSettings)
            print(fileURL)
            self.recorder.record()
            print("Recording started")
            self.record.toggle()
        } catch {
            print(error.localizedDescription)
        }
    } 

func getAudios() {
        
        do {
            
            let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            
            // Fetch all data from document directory
            
            let result = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: .producesRelativePathURLs)
            
            self.audios.removeAll()
            
            for i in result {
                
                self.audios.append(i)
                
            }
            
        }
        catch {
            print(error.localizedDescription)
        }
        
    } 

And this is the function where I get the error in the file.read(into:buf):

func readAudioIntoFloats(fname: String, ext: String) -> [Float] {
            let interleaved: Bool = false
            
            let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            let fileName = url.appendingPathComponent("\(fname).\(ext)")
//            let fileName = Bundle.main.url(forResource: "thump", withExtension: "wav")
            print(fileName)
            let file = try! AVAudioFile(forReading: fileName)
            let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: interleaved)!

            let buf = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 4096*24)!
            do {
                try file.read(into: buf)
            } catch {
                print(error.localizedDescription)
            }
            
            var floatArray: [Float] = []

            if (Int(file.fileFormat.channelCount) == 2) {
                let leftArray = Array(UnsafeBufferPointer(start: buf.floatChannelData?[0], count:Int(buf.frameLength)))
                let rightArray = Array(UnsafeBufferPointer(start: buf.floatChannelData?[1], count:Int(buf.frameLength)))
                
                for i in 0..<leftArray.count {
                    floatArray.append((leftArray[i]+rightArray[i])/Float(2))
                }
            } else {
                
                floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData?[0], count:Int(buf.frameLength)))
                
            }
            
            print(floatArray.count)
            return floatArray

        }

Solution

  • Update: I fixed the problem by setting the category of the session to playandRecord