diff --git a/SyllableDetector/AudioInterface.swift b/SyllableDetector/AudioInterface.swift index d33b9e2..38d5e0b 100644 --- a/SyllableDetector/AudioInterface.swift +++ b/SyllableDetector/AudioInterface.swift @@ -17,7 +17,6 @@ func renderOutput(inRefCon:UnsafeMutablePointer, actionFlags: UnsafeMutabl let buffer = UnsafeMutablePointer(usableBufferList[0].mData) // high settings - let highForLength = aoi.outputHighFor.count let channelCountAsInt = Int(aoi.outputFormat.mChannelsPerFrame) let frameCountAsInt = Int(frameCount) @@ -28,12 +27,7 @@ func renderOutput(inRefCon:UnsafeMutablePointer, actionFlags: UnsafeMutabl // create high for var i = 0; i < frameCountAsInt; ++i { - if channel < highForLength { - buffer[j] = (i < aoi.outputHighFor[channel] ? 1.0 : 0.0) - } - else { - buffer[j] = 0.0 - } + buffer[j] = (i < aoi.outputHighFor[channel] ? 1.0 : 0.0) ++j } @@ -76,7 +70,7 @@ func processInput(inRefCon:UnsafeMutablePointer, actionFlags: UnsafeMutabl let maxi = Int(aii.inputFormat.mChannelsPerFrame) for var i = 0; i < maxi; ++i { // for each channel - aii.delegate?.receiveAudioFrom(aii, fromBuffer: 0, fromChannel: i, withData: data + (i * frameLength), ofLength: frameLength) + aii.delegate?.receiveAudioFrom(aii, fromChannel: i, withData: data + (i * frameLength), ofLength: frameLength) } return 0 @@ -291,6 +285,9 @@ class AudioOutputInterface: AudioInterface assert(2 == outputFormat.mChannelsPerFrame) assert(8 == outputFormat.mBytesPerFrame) + // initiate output array + outputHighFor = [Int](count: Int(outputFormat.mChannelsPerFrame), repeatedValue: 0) + // set frame size var frameSize = UInt32(self.frameSize) try checkError(AudioUnitSetProperty(audioUnit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, outputBus, &frameSize, UInt32(sizeof(UInt32)))) @@ -323,6 +320,11 @@ class AudioOutputInterface: AudioInterface audioUnit = nil } + func createHighOutput(channel: Int, forDuration duration: Double) { + guard channel < Int(outputFormat.mChannelsPerFrame) else { return } + outputHighFor[channel] = Int(duration * outputFormat.mSampleRate) + } + static func defaultOutputDevice() throws -> AudioDeviceID { var size: UInt32 size = UInt32(sizeof(AudioDeviceID)) @@ -335,7 +337,7 @@ class AudioOutputInterface: AudioInterface protocol AudioInputInterfaceDelegate: class { - func receiveAudioFrom(interface: AudioInputInterface, fromBuffer buffer: Int, fromChannel: Int, withData data: UnsafeMutablePointer, ofLength: Int) + func receiveAudioFrom(interface: AudioInputInterface, fromChannel: Int, withData data: UnsafeMutablePointer, ofLength: Int) } class AudioInputInterface: AudioInterface diff --git a/SyllableDetector/ViewControllerProcessor.swift b/SyllableDetector/ViewControllerProcessor.swift index 044c656..661ad9a 100644 --- a/SyllableDetector/ViewControllerProcessor.swift +++ b/SyllableDetector/ViewControllerProcessor.swift @@ -10,22 +10,18 @@ import Cocoa import AudioToolbox struct ProcessorEntry { - let inputBuffer: Int let inputChannel: Int var network: String = "" var config: SyllableDetectorConfig? - let outputBuffer: Int let outputChannel: Int - init(inputBuffer: Int, inputChannel: Int, outputBuffer: Int, outputChannel: Int) { - self.inputBuffer = inputBuffer + init(inputChannel: Int, outputChannel: Int) { self.inputChannel = inputChannel - self.outputBuffer = outputBuffer self.outputChannel = outputChannel } } -class Processor { +class Processor: AudioInputInterfaceDelegate { // input and output interfaces let interfaceInput: AudioInputInterface let interfaceOutput: AudioOutputInterface @@ -34,6 +30,9 @@ class Processor { let entries: [ProcessorEntry] let detectors: [SyllableDetector] + // high duration + let highDuration = 0.001 // 1ms + init(deviceInput: AudioInterface.AudioDevice, deviceOutput: AudioInterface.AudioDevice, entries: [ProcessorEntry]) { // setup processor entries self.entries = entries.filter { @@ -49,6 +48,18 @@ class Processor { interfaceInput = AudioInputInterface(deviceID: deviceInput.deviceID) interfaceOutput = AudioOutputInterface(deviceID: deviceOutput.deviceID) } + + func receiveAudioFrom(interface: AudioInputInterface, fromChannel channel: Int, withData data: UnsafeMutablePointer, ofLength length: Int) { + // valid channel + guard channel < detectors.count else { return } + + // append audio samples + detectors[channel].appendAudioData(data, withSamples: length) + + if detectors[channel].seenSyllable() { + interfaceOutput.createHighOutput(channel, forDuration: highDuration) + } + } } class ViewControllerProcessor: NSViewController, NSTableViewDelegate, NSTableViewDataSource { @@ -61,9 +72,7 @@ class ViewControllerProcessor: NSViewController, NSTableViewDelegate, NSTableVie var deviceOutput: AudioInterface.AudioDevice! var processorEntries = [ProcessorEntry]() - - var syllableDetector: SyllableDetector? - var aiInput: AudioInputInterface? + var processor: Processor? var isRunning = false { didSet { @@ -97,21 +106,26 @@ class ViewControllerProcessor: NSViewController, NSTableViewDelegate, NSTableVie self.deviceOutput = deviceOutput // get input pairs - let inputPairs = deviceInput.buffersInput.enumerate().flatMap { - (b: Int, buffer: AudioBuffer) -> [(Int, Int)] in - return (0.. [(Int, Int)] in - return (0..