Skip to content

Commit

Permalink
Automatically adjust sampling rates based on device.
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanntg committed Nov 3, 2015
1 parent 729ba55 commit 4d7be7c
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 15 deletions.
3 changes: 2 additions & 1 deletion SyllableDetector/SyllableDetector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import AVFoundation

class SyllableDetector: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate
{
let config: SyllableDetectorConfig
// should be constant, but sampling rate can be changed when initializing
var config: SyllableDetectorConfig

// very specific audio settings required, since down sampling signal
var audioSettings: [String: AnyObject] {
Expand Down
33 changes: 30 additions & 3 deletions SyllableDetector/SyllableDetectorConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,43 @@ import Foundation

struct SyllableDetectorConfig
{
let samplingRate: Double // eqv: samplerate
let fourierLength: Int // eqv: FFT_SIZE
let fourierOverlap: Int // eqv: NOVERLAP = FFT_SIZE - (floor(samplerate * FFT_TIME_SHIFT))
var samplingRate: Double // eqv: samplerate
var fourierLength: Int // eqv: FFT_SIZE
var fourierOverlap: Int // eqv: NOVERLAP = FFT_SIZE - (floor(samplerate * FFT_TIME_SHIFT))

let freqRange: (Double, Double) // eqv: freq_range
let timeRange: Int // eqv: time_window_steps = double(floor(time_window / timestep))

let threshold: Double // eqv: trigger threshold

let net: NeuralNet

mutating func modifySamplingRate(newSamplingRate: Double) {
// store old things
let oldSamplingRate = samplingRate
let oldFourierLength = fourierLength
let oldFourierOverlap = fourierOverlap

if oldSamplingRate == newSamplingRate { return }


// get new approximate fourier length
let newApproximateFourierLength = newSamplingRate * Double(oldFourierLength) / oldSamplingRate

// convert to closest power of 2
let newFourierLength = 1 << Int(round(log2(newApproximateFourierLength)))

// get new fourier overlap
let newFourierOverlap = newFourierLength - Int(round(newSamplingRate * Double(oldFourierLength - oldFourierOverlap) / oldSamplingRate))

// change the to new things
samplingRate = newSamplingRate
fourierLength = newFourierLength
fourierOverlap = newFourierOverlap

DLog("New fourier length: \(newFourierLength)")
DLog("New fourier overlap: \(newFourierOverlap)")
}
}

// make parsable
Expand Down
13 changes: 9 additions & 4 deletions SyllableDetector/ViewControllerMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class ViewControllerMenu: NSViewController, WindowControllerProcessorDelegate {
reloadDevices()
}

override func viewDidDisappear() {
// terminate
NSApp.terminate(nil)
}
// override func viewDidDisappear() {
// // terminate
// NSApp.terminate(nil)
// }

func reloadDevices() {
// fetch list of devices
Expand Down Expand Up @@ -106,6 +106,11 @@ class ViewControllerMenu: NSViewController, WindowControllerProcessorDelegate {
controller.delegate = self // custom delegate used to clean up open processor list when windows are closed
controller.showWindow(sender)
openProcessors.append(controller)

// reset selector
selectInput.selectItemAtIndex(0)
selectOutput.selectItemAtIndex(0)
buttonLaunch.enabled = false
}

func windowControllerDone(controller: WindowControllerProcessor) {
Expand Down
9 changes: 5 additions & 4 deletions SyllableDetector/ViewControllerProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,19 @@ class Processor: AudioInputInterfaceDelegate {
// create queue
queueProcessing = dispatch_queue_create("ProcessorQueue", DISPATCH_QUEUE_SERIAL)

// set self as delegate
interfaceInput.delegate = self

try interfaceOutput.initializeAudio()
try interfaceInput.initializeAudio()

// check sampling rates
for d in self.detectors {
if (1 < abs(d.config.samplingRate - interfaceInput.inputFormat.mSampleRate)) {
DLog("Mismatched sampling rates.")
DLog("Mismatched sampling rates. Expecting: \(d.config.samplingRate). Device: \(interfaceInput.inputFormat.mSampleRate).")
d.config.modifySamplingRate(interfaceInput.inputFormat.mSampleRate)
}
}

// set self as delegate
interfaceInput.delegate = self
}

deinit {
Expand Down
6 changes: 3 additions & 3 deletions sample.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AUTOMATICALLY GENERATED SYLLABLE DETECTOR CONFIGURATION
samplingRate = 44100.0
fourierLength = 512
fourierOverlap = 380
samplingRate = 20000.0
fourierLength = 256
fourierOverlap = 196
freqRange = 1992.0, 6992.0
timeRange = 9
threshold = 0.351351351351351
Expand Down

0 comments on commit 4d7be7c

Please sign in to comment.