I've found lots of examples online for working with audio in iOS, but most of them are pretty outdated and don't apply to what I'm trying to accomplish. Here's my project:
I need to capture audio samples from two sources - microphone input and stored audio files. I need to perform FFT on these samples to produce a "fingerprint" for the entire clip, as well as apply some additional filters. The ultimate goal is to build a sort of song-recognition software similar to Shazam, etc.
What is the best way to capture the individual audio samples in iOS 8 for performing a Fast Fourier Transform? I imagine ending up with a large array of them, but I suspect that it might not work quite like that. Secondly, how can I use the Accelerate framework for processing the audio? It seems to be the most efficient way to perform complex analysis on audio in iOS.
All the examples I've seen online are using older versions of iOS and Objective-C, and I haven't been able to successfully translate them into Swift. Does iOS 8 provide some new frameworks for this sort of thing?
AVAudioEngine is the way to go for this. From Apple's docs:
I'll be straight with you: AVAudioEngine is an extremely finicky API with vague documentation, rarely-helpful error messaging, and almost no online code examples demonstrating more than the most basic tasks. BUT if you take the time to get over the small learning curve, you can really do some magical things with it relatively easily.
I've built a simple "playground" view controller that demonstrates both microphone and audio file sampling working in tandem:
The audio samples are given to you via installTap's completion handler which is continuously called as audio passes through the tapped node (either the mic or the audio file player) in real time. You can access individual samples by indexing the sampleData pointer that I've created in each block.
swift
Recording in iOS:
AVAudioRecorder
, as invar audioRecorder: AVAudioRecorder? = nil
AVAudioRecorder
with a URL to store the samples and some record settingsThe recording session sequence:
prepareToRecord()
record()
stop()
Complete Swift/AVAudioRecorder Example
At the heart of your recording method, you could have:
To prepare the recording (streaming to a
file
), you could have:Finally, to stop the recording, use this:
Example above also needs
import AVFoundation
and somerecordSettings
, left to your choice. An example ofrecordSettings
may look like this:Do this, you're done.
You may also want to check out this Stack Overflow answer, which includes a demo project.