func setAKInputDevices() -> [AKDevice]? {
var returnDevices = [AKDevice]()
if let devices = session.availableInputs {
for device in devices {
if device.dataSources == nil {
returnDevices.append(AKDevice(name: device.portName, deviceID: device.uid))
} else {
for dataSource in device.dataSources! {
returnDevices.append(AKDevice(name: device.portName,
deviceID: "\(device.uid) \(dataSource.dataSourceName)"))
}
}
}
return returnDevices
}
return nil
}
func setAKMicrophoneDevice(input: AKDevice) throws {
if let devices = AVAudioSession.sharedInstance().availableInputs {
for device in devices {
if device.dataSources == nil {
if device.uid == input.deviceID {
do {
try AVAudioSession.sharedInstance().setPreferredInput(device)
} catch {
AKLog("Could not set the preferred input to \(input)")
}
}
} else {
for dataSource in device.dataSources! {
if input.deviceID == "\(device.uid) \(dataSource.dataSourceName)" {
do {
try AVAudioSession.sharedInstance().setInputDataSource(dataSource)
} catch {
AKLog("Could not set the preferred input to \(input)")
}
}
}
}
}
}
}
BELOW LIVES IN VIEWDIDLOAD()....
do {
try AKSettings.setSession(category: .playAndRecord, with: [.mixWithOthers, .defaultToSpeaker, .allowBluetoothA2DP])
AKSettings.bufferLength = .medium
session.requestRecordPermission({ (allowed) in
if allowed {
print("allowed recording")
let inputDevices = self.setAKInputDevices()
print(inputDevices)
//TODO: figure out how to set input device to Front mic when headphones are attached.
if let inputs = inputDevices {
do {
self.microphone = AKMicrophone()
for input in inputs {
if input.deviceID.contains("Front") {
try self.setAKMicrophoneDevice(input: input)
}
}
self.micCopy = AKBooster(self.microphone)
self.micCopy.gain = 2.0
self.recordingNode = AKMixer([self.micCopy])
self.configureNodes()
} catch let error {
print("could not access input devices: \(error.localizedDescription)")
}
} else {
print("no input devices found")
}
} else {
print("recording not allowed")
}
})
} catch let error {
print("recording session error: \(error.localizedDescription)")
}
END OF VIEWDIDLOAD()....
func configureNodes() {
do {
let file = try AKAudioFile(forReading: beatURL)
player = try AKAudioPlayer(file: file, looping: true, completionHandler: nil)
passthroughPlayer = AKMixer(player)
recordingNode.connect(player)
} catch let error {
fatalError("Could not read beat URL at \(beatURL): \(error.localizedDescription)")
}
if let player = player {
let waveformWindowSize = CGSize(width: self.view.frame.width, height: self.view.frame.height / 6)
print(beatPlotView.frame)
beatPlot = AKNodeOutputPlot(player, frame: CGRect(origin: beatPlotView.frame.origin, size: waveformWindowSize))
beatPlot.plotType = .buffer
beatPlot.shouldFill = true
beatPlot.backgroundColor = .clear
beatPlot.shouldMirror = true
beatPlot.color = .yellow
recordedAudioPlot = AKNodeOutputPlot(passthroughPlayer, frame: CGRect(origin: recordedAudioPlotView.frame.origin, size: waveformWindowSize))
recordedAudioPlot.plotType = .rolling
recordedAudioPlot.shouldFill = true
recordedAudioPlot.backgroundColor = .clear
recordedAudioPlot.shouldMirror = true
recordedAudioPlot.color = .red
if let micCopy = micCopy {
let micPlot = AKNodeOutputPlot(micCopy, frame: CGRect(origin: beatBufferView.frame.origin, size: waveformWindowSize))
micPlot.plotType = .buffer
micPlot.shouldFill = true
micPlot.backgroundColor = .clear
micPlot.shouldMirror = true
micPlot.color = .blue
self.view.addSubview(micPlot)
}
self.view.addSubview(recordedAudioPlot)
self.view.addSubview(beatPlot)
}
print(AudioKit.outputDevices)
AudioKit.output = passthroughPlayer
AudioKit.start()
player.play()
}
AVAudioSession.sharedInstance().selectBottomDeviceMic()
extension AVAudioSession {
func selectBottomDeviceMic() {
guard let inputs = self.availableInputs else {
return
}
var builtInMicPort: AVAudioSessionPortDescription?
for port in inputs {
if port.portType == AVAudioSessionPortBuiltInMic {
builtInMicPort = port
for source in port.dataSources! {
if source.orientation == AVAudioSessionOrientationBottom {
do {
try builtInMicPort!.setPreferredDataSource(source)
} catch {
print("setPreferredDataSource ERROR")
}
do {
try self.setPreferredInput(builtInMicPort)
} catch {
print("setPreferredInput ERROR")