Skip to content

Commit 7344f8e

Browse files
committed
move plot view to swift
1 parent 738770e commit 7344f8e

File tree

7 files changed

+68
-92
lines changed

7 files changed

+68
-92
lines changed

Formant Analyzer/FormantPlotter.xcodeproj/project.pbxproj

+4-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
D96EF2781888D0C600C570C7 /* blue_light.png in Resources */ = {isa = PBXBuildFile; fileRef = D96EF2751888D0C600C570C7 /* blue_light.png */; };
1515
D97399221C51702000BB2949 /* FirstViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97399211C51702000BB2949 /* FirstViewController.swift */; };
1616
D97399241C5188C400BB2949 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97399231C5188C400BB2949 /* AppDelegate.swift */; };
17+
D97399621C518A0800BB2949 /* FormantPlotView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97399611C518A0800BB2949 /* FormantPlotView.swift */; };
1718
D97AEE131BF2BE97000E4DE4 /* FormantPlotterUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97AEE121BF2BE97000E4DE4 /* FormantPlotterUITests.swift */; };
1819
D97AEE1B1BF2D870000E4DE4 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97AEE1A1BF2D870000E4DE4 /* SnapshotHelper.swift */; };
1920
D985DCC71BFBAD28008B777A /* FormantPlotterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D985DCC61BFBAD28008B777A /* FormantPlotterTests.swift */; };
@@ -32,7 +33,6 @@
3233
D9F7712C1887441E0038839E /* four.raw in Resources */ = {isa = PBXBuildFile; fileRef = D9F771251887441E0038839E /* four.raw */; };
3334
D9F7712D1887441E0038839E /* who.raw in Resources */ = {isa = PBXBuildFile; fileRef = D9F771261887441E0038839E /* who.raw */; };
3435
D9F77136188744320038839E /* vowelPlotBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = D9F77130188744320038839E /* vowelPlotBackground.png */; };
35-
D9F7713F188744AA0038839E /* PlotView.m in Sources */ = {isa = PBXBuildFile; fileRef = D9F7713D188744AA0038839E /* PlotView.m */; };
3636
/* End PBXBuildFile section */
3737

3838
/* Begin PBXContainerItemProxy section */
@@ -64,6 +64,7 @@
6464
D97399201C51701F00BB2949 /* FormantPlotter-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FormantPlotter-Bridging-Header.h"; sourceTree = "<group>"; };
6565
D97399211C51702000BB2949 /* FirstViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = "<group>"; };
6666
D97399231C5188C400BB2949 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
67+
D97399611C518A0800BB2949 /* FormantPlotView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormantPlotView.swift; sourceTree = "<group>"; };
6768
D97AEE101BF2BE97000E4DE4 /* FormantPlotterUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FormantPlotterUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6869
D97AEE121BF2BE97000E4DE4 /* FormantPlotterUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormantPlotterUITests.swift; sourceTree = "<group>"; };
6970
D97AEE141BF2BE97000E4DE4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -91,8 +92,6 @@
9192
D9F771251887441E0038839E /* four.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = four.raw; sourceTree = "<group>"; };
9293
D9F771261887441E0038839E /* who.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = who.raw; sourceTree = "<group>"; };
9394
D9F77130188744320038839E /* vowelPlotBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vowelPlotBackground.png; sourceTree = "<group>"; };
94-
D9F7713C188744AA0038839E /* PlotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlotView.h; sourceTree = "<group>"; };
95-
D9F7713D188744AA0038839E /* PlotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlotView.m; sourceTree = "<group>"; };
9695
/* End PBXFileReference section */
9796

9897
/* Begin PBXFrameworksBuildPhase section */
@@ -195,8 +194,7 @@
195194
D97399231C5188C400BB2949 /* AppDelegate.swift */,
196195
D97399211C51702000BB2949 /* FirstViewController.swift */,
197196
D9F771011887426A0038839E /* Images.xcassets */,
198-
D9F7713C188744AA0038839E /* PlotView.h */,
199-
D9F7713D188744AA0038839E /* PlotView.m */,
197+
D97399611C518A0800BB2949 /* FormantPlotView.swift */,
200198
D913401F1A6DB0D800E3C1C1 /* SpeechAnalyzer.h */,
201199
D91340201A6DB0D800E3C1C1 /* SpeechAnalyzer.m */,
202200
D9F770EA1887426A0038839E /* Supporting Files */,
@@ -435,7 +433,7 @@
435433
buildActionMask = 2147483647;
436434
files = (
437435
D97399241C5188C400BB2949 /* AppDelegate.swift in Sources */,
438-
D9F7713F188744AA0038839E /* PlotView.m in Sources */,
436+
D97399621C518A0800BB2949 /* FormantPlotView.swift in Sources */,
439437
D91340211A6DB0D800E3C1C1 /* SpeechAnalyzer.m in Sources */,
440438
D97399221C51702000BB2949 /* FirstViewController.swift in Sources */,
441439
);

Formant Analyzer/FormantPlotter/Base.lproj/Main.storyboard

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
3232
<nil key="highlightedColor"/>
3333
</label>
34-
<view contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="zrQ-dr-T2a" customClass="PlotView">
34+
<view contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="zrQ-dr-T2a" userLabel="Formant Plot" customClass="FormantPlotView" customModule="FormantPlotter" customModuleProvider="target">
3535
<rect key="frame" x="0.0" y="100" width="320" height="390"/>
3636
<color key="backgroundColor" white="0.93795620440000005" alpha="1" colorSpace="calibratedWhite"/>
3737
</view>
@@ -152,14 +152,14 @@
152152
<navigationItem key="navigationItem" id="Rh5-kw-BCE"/>
153153
<connections>
154154
<outlet property="firstFormantLabel" destination="bJf-am-4MW" id="Ocy-LX-xPB"/>
155+
<outlet property="formantPlot" destination="zrQ-dr-T2a" id="9ni-fs-GKc"/>
155156
<outlet property="fourthFormantLabel" destination="0jX-nd-JdF" id="APb-Pq-l13"/>
156157
<outlet property="graphingMode" destination="AkJ-0Q-cfC" id="L1J-Qp-SGf"/>
157158
<outlet property="indicatorImageView" destination="8Qr-2e-rSY" id="4kP-EA-kby"/>
158159
<outlet property="inputSelector" destination="kgD-9x-g17" id="q9c-UM-eGr"/>
159160
<outlet property="lineChartBottomHalf" destination="Qpg-IJ-E0F" id="IRi-Ew-sXJ"/>
160161
<outlet property="lineChartFull" destination="ERa-1E-mDS" id="MKO-2l-BfQ"/>
161162
<outlet property="lineChartTopHalf" destination="H77-Va-cqM" id="tM8-1e-aCS"/>
162-
<outlet property="plotView" destination="zrQ-dr-T2a" id="Hqa-89-5wo"/>
163163
<outlet property="secondFormantLabel" destination="uAc-hW-WYY" id="BIH-sc-sLo"/>
164164
<outlet property="statusLabel" destination="P33-9r-kcC" id="wOc-wh-IRk"/>
165165
<outlet property="thirdFormantLabel" destination="udF-wh-LHP" id="tTk-Te-c3Z"/>

Formant Analyzer/FormantPlotter/FirstViewController.swift

+8-10
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class FirstViewController: UIViewController {
3333
// Second row
3434
@IBOutlet var graphingMode: UISegmentedControl!
3535
// Third row
36-
@IBOutlet var plotView: PlotView!
36+
@IBOutlet var formantPlot: FormantPlotView!
3737
@IBOutlet var lineChartTopHalf: FSLineChart!
3838
@IBOutlet var lineChartBottomHalf: FSLineChart!
3939
@IBOutlet var lineChartFull: FSLineChart!
@@ -45,7 +45,6 @@ class FirstViewController: UIViewController {
4545

4646
var processingDelayTimeCounter = 0
4747

48-
/// What type of information is to be displayed in self.plotView.
4948
var displayIdentifier: GraphingMode = .Signal
5049

5150
lazy var soundActivatedRecorder: FDSoundActivatedRecorder = {
@@ -86,17 +85,17 @@ class FirstViewController: UIViewController {
8685
self.drawHwPlot()
8786
case .Formant:
8887
//TODO: TEMP HACK
89-
self.plotView.formants = self.speechAnalyzer.findCleanFormants()
90-
self.plotView.hidden = false
88+
self.formantPlot.formants = self.speechAnalyzer.findCleanFormants() as! [Double]
89+
self.formantPlot.hidden = false
9190
self.lineChartTopHalf.hidden = true
9291
self.lineChartBottomHalf.hidden = true
9392
self.lineChartFull.hidden = true
94-
self.plotView.setNeedsDisplay()
93+
self.formantPlot.setNeedsDisplay()
9594
}
9695
}
9796

9897
func drawSignalPlot() {
99-
self.plotView.hidden = true
98+
self.formantPlot.hidden = true
10099
self.lineChartFull.hidden = true
101100
self.lineChartTopHalf.hidden = false
102101
self.lineChartTopHalf.drawInnerGrid = false
@@ -137,7 +136,7 @@ class FirstViewController: UIViewController {
137136
}
138137

139138
func drawLPCPlot() {
140-
self.plotView.hidden = true
139+
self.formantPlot.hidden = true
141140
self.lineChartTopHalf.hidden = true
142141
self.lineChartBottomHalf.hidden = true
143142
self.lineChartFull.hidden = false
@@ -173,7 +172,7 @@ class FirstViewController: UIViewController {
173172
}
174173

175174
func drawHwPlot() {
176-
self.plotView.hidden = true
175+
self.formantPlot.hidden = true
177176
self.lineChartTopHalf.hidden = true
178177
self.lineChartBottomHalf.hidden = true
179178
self.lineChartFull.hidden = false
@@ -240,7 +239,6 @@ class FirstViewController: UIViewController {
240239
}
241240
// Depending upon which stored speech segment is to be processed, the following function loads the appropriate
242241
// binary data file from the main bundle of the app. The loaded data is put into rawBuffer and appropriate view
243-
// is shown in self.plotView.
244242
// If we are looking at 5th plot type (formant frequencies), four text labels are updated with a delay of 0.5 sec
245243

246244
func processRawBuffer() {
@@ -298,7 +296,7 @@ class FirstViewController: UIViewController {
298296
//TODO should not be here!?
299297
/// Get raw PCM data from the track
300298
func readSoundFileSamples(filePath: String) -> NSData {
301-
var retval = NSMutableData()
299+
let retval = NSMutableData()
302300
let assetURL: NSURL = NSURL(fileURLWithPath: filePath)
303301
let asset = AVURLAsset(URL: assetURL)
304302
let track = asset.tracks[0]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// FormantPlotView.swift
3+
// FormantPlotter
4+
//
5+
// Created by William Entriken on 1/21/16.
6+
// Copyright © 2016 William Entriken. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
class FormantPlotView: UIView {
12+
var formants = [Double]()
13+
14+
/// The main display routine
15+
override func drawRect(rect: CGRect) {
16+
//TODO can do better!
17+
for view in self.subviews {
18+
view.removeFromSuperview()
19+
}
20+
21+
guard self.formants.count >= 3 else {
22+
return
23+
}
24+
25+
//TODO: maybe do this first
26+
// Now, we add an image to current view to plot location of first two formants
27+
let backgroundRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)
28+
let backgroundImageView = UIImageView(frame: backgroundRect)
29+
backgroundImageView.image = UIImage(named: "vowelPlotBackground.png")
30+
self.addSubview(backgroundImageView)
31+
32+
// Choose the two formants we want to plot
33+
// If FF[2] is too close to FF[1], use FF[3] for vertical axis.
34+
let plottingFmtX = self.formants[0]
35+
let plottingFmtY: Double
36+
if self.formants[1] > 1.6 * self.formants[0] {
37+
plottingFmtY = self.formants[1]
38+
} else {
39+
plottingFmtY = self.formants[2]
40+
}
41+
42+
// Translate from formant in Hz to x/y position as a portion of plot image
43+
// Need to consider scale of plot image and make it line up
44+
let plottingX = 0.103 + (plottingFmtX - 0) / 1200 * (0.953 - 0.103)
45+
let logPart = log(plottingFmtY) / log(2.0) - log(500.0) / log(2.0)
46+
let plottingY = (1.00 - 0.134) - logPart * (0.414 - 0.134)
47+
// Now translate into coordinate system of this image view
48+
let markerRect: CGRect = CGRectMake(self.frame.size.width * CGFloat(plottingX) - 7.5, self.frame.size.height * CGFloat(plottingY) - 7.5, 15.0, 15.0)
49+
let markerImageView: UIImageView = UIImageView(frame: markerRect)
50+
markerImageView.backgroundColor = UIColor.blackColor()
51+
self.addSubview(markerImageView)
52+
//MAYBE: if the f1 <= 1.6 * f2, consider plotting a second mark where the f2 actually is rathen than using f3
53+
}
54+
}

Formant Analyzer/FormantPlotter/FormantPlotter-Bridging-Header.h

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use this file to import your target's public headers that you would like to expose to Swift.
33
//
44

5-
#import "PlotView.h"
65
#import <FSLineChart.h>
76
#import <TOWebViewController.h>
87
#import <FDSoundActivatedRecorder.h>

Formant Analyzer/FormantPlotter/PlotView.h

-18
This file was deleted.

Formant Analyzer/FormantPlotter/PlotView.m

-55
This file was deleted.

0 commit comments

Comments
 (0)