4

I have a problem in an app I'm developing where eventually too many audio files wind up being open. I haven't found any way to close the files, so I've tried setting files that aren't being used to nil, but the problem is persisting.

I've declared the audio files as non-optionals, ex:

let audioFile1 = AKAudioFile!

and in the method they are being initialized, the initialization fails (after too many files have been opened) in the following block of code (audioUrl is a one of the method's parameters):

 var audioFileOpt: AKAudioFile?
        
        do {
            audioFileOpt = try AKAudioFile(forReading: audioUrl)
            
        } catch let error {
            print("Error reading url: ", audioUrl)
            print(error.localizedDescription)
        }

This is the error that is returned: The operation couldn\U2019t be completed. (com.apple.coreaudio.avfaudio error -42.), which is a CoreAudio error (kAudio_TooManyFilesOpenError).

I'd appreciate any advice on how to go about solving this.

lxirsh
  • 93
  • 8
  • I'd expect that not holding a reference to the object would be enough. How many audio files are you opening? On OS X, you can try using the `lsof` command to see what file descriptors a process has open and verify that the audio files are the primary offender. – user1325158 Feb 05 '21 at 02:43

1 Answers1

1

Whilst this is not closing a file (I too couldn't find a way to do this), the below resolves the error you were getting:

You need to increase the number of open files to avoid the com.apple.coreaudio.avfaudio error -42 - CoreAudio error (kAudio_TooManyFilesOpenError. The default limit of audio files AVAudioPlayer can handle is 256. Here's an objective-c solution.

Insert this in AppDelegate.h

#include <stdio.h>
#include <sys/resource.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

Insert this in AppDelegate.m, didFinishLaunchingWithOptions method

struct rlimit limit;
getrlimit(RLIMIT_NOFILE, &limit);
limit.rlim_cur = 5120; // This gives 20x more than default, but change accordingly
setrlimit(RLIMIT_NOFILE, &limit);
getrlimit(RLIMIT_NOFILE, &limit);
TomV
  • 1,157
  • 1
  • 13
  • 25