Skip to content

Commit

Permalink
Resize syllable config before creating detector (bug in fourier trans…
Browse files Browse the repository at this point in the history
…form).
  • Loading branch information
nathanntg committed Nov 3, 2015
1 parent 4d7be7c commit e77b794
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 29 deletions.
3 changes: 3 additions & 0 deletions SyllableDetector.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
TargetAttributes = {
D8625C781BE14922000922D8 = {
CreatedOnToolsVersion = 7.1;
DevelopmentTeam = WRZPP65FJN;
};
};
};
Expand Down Expand Up @@ -286,6 +287,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Developer ID Application";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = SyllableDetector/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
Expand All @@ -300,6 +302,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Developer ID Application";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = SyllableDetector/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
Expand Down
47 changes: 33 additions & 14 deletions SyllableDetector/AudioInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,26 @@ func renderOutput(inRefCon:UnsafeMutablePointer<Void>, actionFlags: UnsafeMutabl
// get audio out interface
let aoi = unsafeBitCast(inRefCon, AudioOutputInterface.self)
let usableBufferList = UnsafeMutableAudioBufferListPointer(data)
let buffer = UnsafeMutablePointer<Float>(usableBufferList[0].mData)

// high settings
let channelCountAsInt = Int(aoi.outputFormat.mChannelsPerFrame)
// number of frames
let frameCountAsInt = Int(frameCount)

// fill output
var j = 0
for var channel = 0; channel < channelCountAsInt; ++channel {
// TODO: must be faster way to fill vectors using vDSP
for (channel, buffer) in usableBufferList.enumerate() {
let data = UnsafeMutablePointer<Float>(buffer.mData)
let high = aoi.outputHighFor[channel]

// create high
for var i = 0; i < frameCountAsInt; ++i {
buffer[j] = (i < aoi.outputHighFor[channel] ? 1.0 : 0.0)
++j
// decrement high for
if 0 < high {
aoi.outputHighFor[channel] = high - min(high, frameCountAsInt)
DLog("write high")
}

// decrement high for
if 0 < aoi.outputHighFor[channel] {
aoi.outputHighFor[channel] = aoi.outputHighFor[channel] - min(aoi.outputHighFor[channel], frameCountAsInt)
// write data out
for var i = 0; i < frameCountAsInt; ++i {
data[i] = (i < high ? 1.0 : 0.0)
}

}

return 0
Expand Down Expand Up @@ -65,7 +64,7 @@ func processInput(inRefCon:UnsafeMutablePointer<Void>, actionFlags: UnsafeMutabl
// number of floats per channel
let frameCountAsInteger = Int(frameCount)

// multiple channels? de-interleave
// multiple channels
for var channel = 0; channel < numberOfChannels; ++channel {
// call delegate
aii.delegate?.receiveAudioFrom(aii, fromChannel: channel, withData: UnsafeMutablePointer<Float>(aii.bufferList[channel].mData), ofLength: frameCountAsInteger)
Expand Down Expand Up @@ -100,6 +99,8 @@ class AudioInterface
let deviceManufacturer: String
let streamsInput: Int
let streamsOutput: Int
let sampleRateInput: Float64
let sampleRateOutput: Float64
let buffersInput: [AudioBuffer]
let buffersOutput: [AudioBuffer]

Expand Down Expand Up @@ -143,6 +144,14 @@ class AudioInterface
self.streamsInput = Int(size) / sizeof(AudioStreamID)

if 0 < self.streamsInput {
// get sample rate
size = UInt32(sizeof(Float64))
var sampleRateInput: Float64 = 0.0
propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate
status = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &size, &sampleRateInput)
guard noErr == status else { return nil }
self.sampleRateInput = sampleRateInput

// get stream configuration
size = 0
propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration
Expand All @@ -169,6 +178,7 @@ class AudioInterface
}
else {
self.buffersInput = []
self.sampleRateInput = 0.0
}

propertyAddress.mSelector = kAudioDevicePropertyStreams
Expand All @@ -178,6 +188,14 @@ class AudioInterface
self.streamsOutput = Int(size) / sizeof(AudioStreamID)

if 0 < self.streamsOutput {
// get sample rate
size = UInt32(sizeof(Float64))
var sampleRateOutput: Float64 = 0.0
propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate
status = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &size, &sampleRateOutput)
guard noErr == status else { return nil }
self.sampleRateOutput = sampleRateOutput

// get stream configuration
size = 0
propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration
Expand All @@ -204,6 +222,7 @@ class AudioInterface
}
else {
self.buffersOutput = []
self.sampleRateOutput = 0.0
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions SyllableDetector/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>2</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.education</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
Expand Down
2 changes: 1 addition & 1 deletion SyllableDetector/SyllableDetector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import AVFoundation
class SyllableDetector: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate
{
// should be constant, but sampling rate can be changed when initializing
var config: SyllableDetectorConfig
let config: SyllableDetectorConfig

// very specific audio settings required, since down sampling signal
var audioSettings: [String: AnyObject] {
Expand Down
20 changes: 8 additions & 12 deletions SyllableDetector/ViewControllerProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,6 @@ class Processor: AudioInputInterfaceDelegate {
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. Expecting: \(d.config.samplingRate). Device: \(interfaceInput.inputFormat.mSampleRate).")
d.config.modifySamplingRate(interfaceInput.inputFormat.mSampleRate)
}
}

// set self as delegate
interfaceInput.delegate = self
}
Expand All @@ -96,9 +88,6 @@ class Processor: AudioInputInterfaceDelegate {
// process
dispatch_async(queueProcessing) {
if self.detectors[index].seenSyllable() {
// record playing
DLog("\(channel) play")

// play high
self.interfaceOutput.createHighOutput(self.entries[index].outputChannel, forDuration: self.highDuration)
}
Expand Down Expand Up @@ -323,7 +312,14 @@ class ViewControllerProcessor: NSViewController, NSTableViewDelegate, NSTableVie
if let url = panel.URL, let path = url.path {
do {
// load file
let config = try SyllableDetectorConfig(fromTextFile: path)
var config = try SyllableDetectorConfig(fromTextFile: path)

// check sampling rate
if (1 < abs(config.samplingRate - self.deviceInput.sampleRateInput)) {
DLog("Mismatched sampling rates. Expecting: \(config.samplingRate). Device: \(self.deviceInput.sampleRateInput).")
config.modifySamplingRate(self.deviceInput.sampleRateInput)
}

self.processorEntries[row].config = config
self.processorEntries[row].network = url.lastPathComponent ?? "Unknown Network"
}
Expand Down

0 comments on commit e77b794

Please sign in to comment.