diff --git a/.swift-version b/.swift-version index 9f55b2c..5186d07 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.0 +4.0 diff --git a/.travis.yml b/.travis.yml index 788a38c..95895db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ -osx_image: xcode8 +osx_image: xcode9 language: objective-c +xcode_sdk: iphonesimulator10.0 before_install: - brew update @@ -7,8 +8,8 @@ before_install: - travis_wait 35 carthage bootstrap --platform iOS script: -- xcodebuild clean build -project Beethoven.xcodeproj -scheme "Beethoven-iOS" -sdk iphonesimulator | xcpretty && exit ${PIPESTATUS[0]} -- xcodebuild test -project Beethoven.xcodeproj -scheme "Beethoven-iOS" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.0' | xcpretty && exit ${PIPESTATUS[0]} +- set -o pipefail +- travis_retry xcodebuild -project Beethoven.xcodeproj -scheme "Beethoven-iOS" -destination "platform=iOS Simulator,name=iPhone 6" build-for-testing test | xcpretty notifications: email: false diff --git a/Beethoven.podspec b/Beethoven.podspec index 7f7e044..435d5ea 100644 --- a/Beethoven.podspec +++ b/Beethoven.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "Beethoven" s.summary = "A maestro of pitch detection" - s.version = "3.0.1" + s.version = "4.0.0" s.homepage = "https://github.com/vadymmarkov/Beethoven" s.license = 'MIT' s.author = { "Vadym Markov" => "markov.vadym@gmail.com" } @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.ios.source_files = 'Source/**/*' s.frameworks = 'Foundation', 'AVFoundation', 'Accelerate' - s.dependency 'Pitchy' + s.dependency 'Pitchy', '~> 3.0' s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' } end diff --git a/Beethoven.xcodeproj/project.pbxproj b/Beethoven.xcodeproj/project.pbxproj index 103ccf7..d2b38f9 100644 --- a/Beethoven.xcodeproj/project.pbxproj +++ b/Beethoven.xcodeproj/project.pbxproj @@ -377,16 +377,16 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Vadym Markov"; TargetAttributes = { D51575AA1C343B77006F8E75 = { CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; D51575B41C343B77006F8E75 = { CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; }; }; @@ -539,14 +539,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -589,14 +595,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -644,7 +656,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.Beethoven; PRODUCT_NAME = Beethoven; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -667,7 +680,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.Beethoven; PRODUCT_NAME = Beethoven; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -684,7 +698,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.BeethovenTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -700,7 +715,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.BeethovenTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Beethoven.xcodeproj/xcshareddata/xcschemes/Beethoven-iOS.xcscheme b/Beethoven.xcodeproj/xcshareddata/xcschemes/Beethoven-iOS.xcscheme index 6ea43e3..c79b949 100644 --- a/Beethoven.xcodeproj/xcshareddata/xcschemes/Beethoven-iOS.xcscheme +++ b/Beethoven.xcodeproj/xcshareddata/xcschemes/Beethoven-iOS.xcscheme @@ -1,6 +1,6 @@ /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 1962EBAD1F8E34314E982594 /* [CP] Check Pods Manifest.lock */ = { @@ -237,9 +240,18 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-GuitarTuner/Pods-GuitarTuner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Beethoven/Beethoven.framework", + "${BUILT_PRODUCTS_DIR}/Cartography/Cartography.framework", + "${BUILT_PRODUCTS_DIR}/Hue/Hue.framework", + "${BUILT_PRODUCTS_DIR}/Pitchy/Pitchy.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Beethoven.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cartography.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Hue.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Pitchy.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -310,14 +322,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -357,14 +375,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -401,7 +425,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.GuitarTuner; PRODUCT_NAME = GuitarTuner; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -416,7 +441,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.vadymmarkov.GuitarTuner; PRODUCT_NAME = GuitarTuner; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Example/GuitarTuner/GuitarTuner/Source/AppDelegate.swift b/Example/GuitarTuner/GuitarTuner/Source/AppDelegate.swift index cfb1649..d0267a3 100644 --- a/Example/GuitarTuner/GuitarTuner/Source/AppDelegate.swift +++ b/Example/GuitarTuner/GuitarTuner/Source/AppDelegate.swift @@ -3,20 +3,12 @@ import Hue @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? + lazy var navigationController: UINavigationController = .init(rootViewController: self.viewController) + lazy var viewController: ViewController = .init() - lazy var navigationController: UINavigationController = { [unowned self] in - let controller = UINavigationController(rootViewController: self.viewController) - return controller - }() - - lazy var viewController: ViewController = { - let controller = ViewController() - return controller - }() - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = navigationController @@ -27,14 +19,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func applyStyles() { + private func applyStyles() { let navigationBar = UINavigationBar.appearance() navigationBar.barStyle = .black navigationBar.barTintColor = UIColor(hex: "111011") navigationBar.isTranslucent = false navigationBar.shadowImage = UIImage() navigationBar.titleTextAttributes = [ - NSForegroundColorAttributeName: UIColor.white + NSAttributedStringKey.foregroundColor: UIColor.white ] } } diff --git a/Example/GuitarTuner/GuitarTuner/Source/ViewController.swift b/Example/GuitarTuner/GuitarTuner/Source/ViewController.swift index e09923c..e82a165 100644 --- a/Example/GuitarTuner/GuitarTuner/Source/ViewController.swift +++ b/Example/GuitarTuner/GuitarTuner/Source/ViewController.swift @@ -4,8 +4,7 @@ import Pitchy import Hue import Cartography -class ViewController: UIViewController { - +final class ViewController: UIViewController { lazy var noteLabel: UILabel = { let label = UILabel() label.text = "--" @@ -14,9 +13,8 @@ class ViewController: UIViewController { label.textAlignment = .center label.numberOfLines = 0 label.sizeToFit() - return label - }() + }() lazy var offsetLabel: UILabel = { let label = UILabel() @@ -25,9 +23,8 @@ class ViewController: UIViewController { label.textAlignment = .center label.numberOfLines = 0 label.sizeToFit() - return label - }() + }() lazy var actionButton: UIButton = { [unowned self] in let button = UIButton(type: .system) @@ -41,15 +38,14 @@ class ViewController: UIViewController { button.setTitle("Start".uppercased(), for: UIControlState()) return button - }() + }() lazy var pitchEngine: PitchEngine = { [weak self] in - var config = Config(estimationStrategy: .yin) + let config = Config(estimationStrategy: .yin) let pitchEngine = PitchEngine(config: config, delegate: self) pitchEngine.levelThreshold = -30.0 - return pitchEngine - }() + }() // MARK: - View Lifecycle @@ -68,7 +64,7 @@ class ViewController: UIViewController { // MARK: - Action methods - func actionButtonDidPress(_ button: UIButton) { + @objc func actionButtonDidPress(_ button: UIButton) { let text = pitchEngine.active ? NSLocalizedString("Start", comment: "").uppercased() : NSLocalizedString("Stop", comment: "").uppercased() @@ -112,7 +108,7 @@ class ViewController: UIViewController { // MARK: - UI - func offsetColor(_ offsetPercentage: Double) -> UIColor { + private func offsetColor(_ offsetPercentage: Double) -> UIColor { let color: UIColor switch abs(offsetPercentage) { @@ -131,8 +127,7 @@ class ViewController: UIViewController { // MARK: - PitchEngineDelegate extension ViewController: PitchEngineDelegate { - - func pitchEngineDidReceivePitch(_ pitchEngine: PitchEngine, pitch: Pitch) { + func pitchEngine(_ pitchEngine: PitchEngine, didReceivePitch pitch: Pitch) { noteLabel.text = pitch.note.string let offsetPercentage = pitch.closestOffset.percentage @@ -152,7 +147,7 @@ extension ViewController: PitchEngineDelegate { offsetLabel.isHidden = false } - func pitchEngineDidReceiveError(_ pitchEngine: PitchEngine, error: Error) { + func pitchEngine(_ pitchEngine: PitchEngine, didReceiveError error: Error) { print(error) } diff --git a/Example/GuitarTuner/Podfile b/Example/GuitarTuner/Podfile index 86f50a5..edd92fd 100644 --- a/Example/GuitarTuner/Podfile +++ b/Example/GuitarTuner/Podfile @@ -1,18 +1,9 @@ use_frameworks! -platform :ios, '8.0' +platform :ios, '9.0' target 'GuitarTuner' do pod 'Beethoven', path: '../../' - pod 'Hue', git: 'https://github.com/hyperoslo/Hue' + pod 'Hue', '~> 3.0' pod 'Cartography' end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['SWIFT_VERSION'] = '3.0' - end - end -end - diff --git a/Example/GuitarTuner/Podfile.lock b/Example/GuitarTuner/Podfile.lock index 72db953..2745cc9 100644 --- a/Example/GuitarTuner/Podfile.lock +++ b/Example/GuitarTuner/Podfile.lock @@ -1,32 +1,25 @@ PODS: - - Beethoven (3.0.0): - - Pitchy - - Cartography (1.0.1) - - Hue (2.0.0) - - Pitchy (2.0.1) + - Beethoven (4.0.0): + - Pitchy (~> 3.0) + - Cartography (2.0.0) + - Hue (3.0.0) + - Pitchy (3.0.0) DEPENDENCIES: - Beethoven (from `../../`) - Cartography - - Hue (from `https://github.com/hyperoslo/Hue`) + - Hue (~> 3.0) EXTERNAL SOURCES: Beethoven: - :path: "../../" - Hue: - :git: https://github.com/hyperoslo/Hue - -CHECKOUT OPTIONS: - Hue: - :commit: 9588169ba4201e8a1038a3d2c1750843bf90d7e0 - :git: https://github.com/hyperoslo/Hue + :path: ../../ SPEC CHECKSUMS: - Beethoven: 70d27286285b8d2a80c253b3da7db9b0d1157425 - Cartography: c1460e99395b824d9d75360b0382faeb0b33dcd7 - Hue: 2b317616a04cc5d7cccdb024c88e6d143e2b9cf1 - Pitchy: 00dbe7cb7ac87fd9c32cb2aa6ce50d11f931289f + Beethoven: 0cb6d02eace9841d29fcb52f92334d2bd4c8e131 + Cartography: d295eb25ab54bb57eecd8c2f04e9648c850f1281 + Hue: b8fe1e43eef13631331eebecb2198b68e2622f95 + Pitchy: 15407e4425b6d88fa3e7eef8927ba659fab52d7a -PODFILE CHECKSUM: 1e153b4e2c75610a8ffdfdf508f1f60b13da109d +PODFILE CHECKSUM: 38c90b3edadf248124cd55d1086854ecf4e5c51b -COCOAPODS: 1.1.0.rc.3 +COCOAPODS: 1.3.1 diff --git a/README.md b/README.md index 12cada9..e5fcd93 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CI Status](http://img.shields.io/travis/vadymmarkov/Beethoven.svg?style=flat)](https://travis-ci.org/vadymmarkov/Beethoven) [![Version](https://img.shields.io/cocoapods/v/Beethoven.svg?style=flat)](http://cocoadocs.org/docsets/Beethoven) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -![Swift](https://img.shields.io/badge/%20in-swift%203.0-orange.svg) +![Swift](https://img.shields.io/badge/%20in-swift%204.0-orange.svg) [![License](https://img.shields.io/cocoapods/l/Beethoven.svg?style=flat)](http://cocoadocs.org/docsets/Beethoven) [![Platform](https://img.shields.io/cocoapods/p/Beethoven.svg?style=flat)](http://cocoadocs.org/docsets/Beethoven) @@ -104,8 +104,8 @@ pitchEngine.delegate = pitchEngineDelegate the pitch detection has been started: ```swift -func pitchEngineDidReceivePitch(_ pitchEngine: PitchEngine, pitch: Pitch) -func pitchEngineDidReceiveError(_ pitchEngine: PitchEngine, error: Error) +func pitchEngine(_ pitchEngine: PitchEngine, didReceivePitch pitch: Pitch) +func pitchEngine(_ pitchEngine: PitchEngine, didReceiveError error: Error) func pitchEngineWentBelowLevelThreshold(_ pitchEngine: PitchEngine) ``` diff --git a/Source/Config.swift b/Source/Config.swift index eff7c99..dab44c2 100644 --- a/Source/Config.swift +++ b/Source/Config.swift @@ -1,16 +1,15 @@ import AVFoundation public struct Config { - - public var bufferSize: AVAudioFrameCount - public var estimationStrategy: EstimationStrategy - public var audioUrl: URL? + public let bufferSize: AVAudioFrameCount + public let estimationStrategy: EstimationStrategy + public let audioUrl: URL? // MARK: - Initialization public init(bufferSize: AVAudioFrameCount = 4096, - estimationStrategy: EstimationStrategy = .yin, - audioUrl: URL? = nil) { + estimationStrategy: EstimationStrategy = .yin, + audioUrl: URL? = nil) { self.bufferSize = bufferSize self.estimationStrategy = estimationStrategy self.audioUrl = audioUrl diff --git a/Source/Estimation/EstimationFactory.swift b/Source/Estimation/EstimationFactory.swift index cb1af52..ce29db6 100644 --- a/Source/Estimation/EstimationFactory.swift +++ b/Source/Estimation/EstimationFactory.swift @@ -1,6 +1,5 @@ -struct EstimationFactory { - - static func create(_ strategy: EstimationStrategy) -> Estimator { +final class EstimationFactory { + func create(_ strategy: EstimationStrategy) -> Estimator { let estimator: Estimator switch strategy { diff --git a/Source/Estimation/Estimator.swift b/Source/Estimation/Estimator.swift index bcfdc3f..dac2b9f 100644 --- a/Source/Estimation/Estimator.swift +++ b/Source/Estimation/Estimator.swift @@ -1,20 +1,16 @@ protocol Estimator { var transformer: Transformer { get } - func estimateFrequency(sampleRate: Float, buffer: Buffer) throws -> Float func estimateFrequency(sampleRate: Float, location: Int, bufferCount: Int) -> Float } -extension Estimator { - - // MARK: - Default implementation +// MARK: - Default implementations +extension Estimator { func estimateFrequency(sampleRate: Float, location: Int, bufferCount: Int) -> Float { return Float(location) * sampleRate / (Float(bufferCount) * 2) } - // MARK: - Helpers - func maxBufferIndex(from buffer: [Float]) throws -> Int { guard buffer.count > 0 else { throw EstimationError.emptyBuffer diff --git a/Source/Estimation/LocationEstimator.swift b/Source/Estimation/LocationEstimator.swift index 8fb1542..2630754 100644 --- a/Source/Estimation/LocationEstimator.swift +++ b/Source/Estimation/LocationEstimator.swift @@ -2,10 +2,9 @@ protocol LocationEstimator: Estimator { func estimateLocation(buffer: Buffer) throws -> Int } -extension LocationEstimator { - - // MARK: - Default implementation +// MARK: - Default implementation +extension LocationEstimator { var transformer: Transformer { return FFTTransformer() } diff --git a/Source/Estimation/Strategies/BarycentricEstimator.swift b/Source/Estimation/Strategies/BarycentricEstimator.swift index d7a7fbe..a91fafd 100644 --- a/Source/Estimation/Strategies/BarycentricEstimator.swift +++ b/Source/Estimation/Strategies/BarycentricEstimator.swift @@ -1,7 +1,6 @@ import Foundation -struct BarycentricEstimator: LocationEstimator { - +final class BarycentricEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { let elements = buffer.elements let maxIndex = try maxBufferIndex(from: elements) diff --git a/Source/Estimation/Strategies/HPSEstimator.swift b/Source/Estimation/Strategies/HPSEstimator.swift index fca5aa6..21d2380 100644 --- a/Source/Estimation/Strategies/HPSEstimator.swift +++ b/Source/Estimation/Strategies/HPSEstimator.swift @@ -1,7 +1,6 @@ -struct HPSEstimator: LocationEstimator { - - let harmonics = 5 - let minIndex = 20 +final class HPSEstimator: LocationEstimator { + private let harmonics = 5 + private let minIndex = 20 func estimateLocation(buffer: Buffer) throws -> Int { var spectrum = buffer.elements @@ -32,6 +31,7 @@ struct HPSEstimator: LocationEstimator { maxsearch = location } + // swiftlint:disable for_where for i in (minIndex + 1).. spectrum[max2] { max2 = i diff --git a/Source/Estimation/Strategies/JainsEstimator.swift b/Source/Estimation/Strategies/JainsEstimator.swift index af2e166..f084fcb 100644 --- a/Source/Estimation/Strategies/JainsEstimator.swift +++ b/Source/Estimation/Strategies/JainsEstimator.swift @@ -1,7 +1,6 @@ import Foundation -struct JainsEstimator: LocationEstimator { - +final class JainsEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { let elements = buffer.elements let maxIndex = try maxBufferIndex(from: elements) diff --git a/Source/Estimation/Strategies/MaxValueEstimator.swift b/Source/Estimation/Strategies/MaxValueEstimator.swift index 16c3942..7000dc7 100644 --- a/Source/Estimation/Strategies/MaxValueEstimator.swift +++ b/Source/Estimation/Strategies/MaxValueEstimator.swift @@ -1,5 +1,4 @@ -struct MaxValueEstimator: LocationEstimator { - +final class MaxValueEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { return try maxBufferIndex(from: buffer.elements) } diff --git a/Source/Estimation/Strategies/QuadradicEstimator.swift b/Source/Estimation/Strategies/QuadradicEstimator.swift index 811ce6f..41f5c38 100644 --- a/Source/Estimation/Strategies/QuadradicEstimator.swift +++ b/Source/Estimation/Strategies/QuadradicEstimator.swift @@ -1,7 +1,6 @@ import Foundation -struct QuadradicEstimator: LocationEstimator { - +final class QuadradicEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { let elements = buffer.elements let maxIndex = try maxBufferIndex(from: elements) diff --git a/Source/Estimation/Strategies/QuinnsFirstEstimator.swift b/Source/Estimation/Strategies/QuinnsFirstEstimator.swift index 535c30d..74a87ca 100644 --- a/Source/Estimation/Strategies/QuinnsFirstEstimator.swift +++ b/Source/Estimation/Strategies/QuinnsFirstEstimator.swift @@ -1,7 +1,6 @@ import Foundation -struct QuinnsFirstEstimator: LocationEstimator { - +final class QuinnsFirstEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { let elements = buffer.elements let maxIndex = try maxBufferIndex(from: elements) diff --git a/Source/Estimation/Strategies/QuinnsSecondEstimator.swift b/Source/Estimation/Strategies/QuinnsSecondEstimator.swift index 1987324..ceb0383 100644 --- a/Source/Estimation/Strategies/QuinnsSecondEstimator.swift +++ b/Source/Estimation/Strategies/QuinnsSecondEstimator.swift @@ -1,7 +1,6 @@ import Foundation -struct QuinnsSecondEstimator: LocationEstimator { - +final class QuinnsSecondEstimator: LocationEstimator { func estimateLocation(buffer: Buffer) throws -> Int { let elements = buffer.elements let maxIndex = try maxBufferIndex(from: elements) @@ -27,7 +26,7 @@ struct QuinnsSecondEstimator: LocationEstimator { return sanitize(location: location, reserveLocation: maxIndex, elements: elements) } - func tau(_ x: Float) -> Float { + private func tau(_ x: Float) -> Float { let p1 = log(3 * pow(x, 2.0) + 6 * x + 1) let part1 = x + 1 - sqrt(2/3) let part2 = x + 1 + sqrt(2/3) diff --git a/Source/Estimation/Strategies/YINEstimator.swift b/Source/Estimation/Strategies/YINEstimator.swift index c542b71..dce1d6b 100644 --- a/Source/Estimation/Strategies/YINEstimator.swift +++ b/Source/Estimation/Strategies/YINEstimator.swift @@ -8,8 +8,7 @@ import UIKit -struct YINEstimator: Estimator { - +final class YINEstimator: Estimator { let transformer: Transformer = YINTransformer() let threshold: Float = 0.05 diff --git a/Source/Library/Buffer.swift b/Source/Library/Buffer.swift index 970b22c..7ca68ff 100644 --- a/Source/Library/Buffer.swift +++ b/Source/Library/Buffer.swift @@ -1,5 +1,4 @@ struct Buffer { - var elements: [Float] var realElements: [Float]? var imagElements: [Float]? diff --git a/Source/Library/Extensions/Array+Extensions.swift b/Source/Library/Extensions/Array+Extensions.swift index f0eab8d..33a41db 100644 --- a/Source/Library/Extensions/Array+Extensions.swift +++ b/Source/Library/Extensions/Array+Extensions.swift @@ -1,5 +1,4 @@ extension Array where Element:Comparable { - static func fromUnsafePointer(_ data: UnsafePointer, count: Int) -> [Element] { let buffer = UnsafeBufferPointer(start: data, count: count) return Array(buffer) diff --git a/Source/Library/YINUtil.swift b/Source/Library/YINUtil.swift index dec9acf..2b970aa 100644 --- a/Source/Library/YINUtil.swift +++ b/Source/Library/YINUtil.swift @@ -11,8 +11,7 @@ import UIKit import Accelerate -class YINUtil { - +final class YINUtil { // Slow and eats a lot of CPU, but working class func difference2(buffer: [Float]) -> [Float] { let bufferHalfCount = buffer.count / 2 @@ -57,8 +56,8 @@ class YINUtil { // https://code.soundsoftware.ac.uk/projects/pyin/repository but I don't know what // // Kept for reference only. + // swiftlint:disable function_body_length class func difference_broken_do_not_use(buffer: [Float]) -> [Float] { - let frameSize = buffer.count let yinBufferSize = frameSize / 2 diff --git a/Source/PitchEngine.swift b/Source/PitchEngine.swift index 4be617b..27e94a3 100644 --- a/Source/PitchEngine.swift +++ b/Source/PitchEngine.swift @@ -3,24 +3,23 @@ import AVFoundation import Pitchy public protocol PitchEngineDelegate: class { - func pitchEngineDidReceivePitch(_ pitchEngine: PitchEngine, pitch: Pitch) - func pitchEngineDidReceiveError(_ pitchEngine: PitchEngine, error: Error) + func pitchEngine(_ pitchEngine: PitchEngine, didReceivePitch pitch: Pitch) + func pitchEngine(_ pitchEngine: PitchEngine, didReceiveError error: Error) func pitchEngineWentBelowLevelThreshold(_ pitchEngine: PitchEngine) } -public enum PitchEngineError: Error { - case recordPermissionDenied -} - -public class PitchEngine { +public final class PitchEngine { + public enum Error: Swift.Error { + case recordPermissionDenied + } public let bufferSize: AVAudioFrameCount - public var active = false + public private(set) var active = false public weak var delegate: PitchEngineDelegate? - fileprivate var estimator: Estimator - fileprivate var signalTracker: SignalTracker - fileprivate var queue: DispatchQueue + private let estimator: Estimator + private let signalTracker: SignalTracker + private let queue: DispatchQueue public var mode: SignalTrackerMode { return signalTracker.mode @@ -36,14 +35,18 @@ public class PitchEngine { } public var signalLevel: Float { - get { return signalTracker.averageLevel ?? 0.0 } + return signalTracker.averageLevel ?? 0.0 } // MARK: - Initialization - public init(config: Config = Config(), signalTracker: SignalTracker? = nil, delegate: PitchEngineDelegate? = nil) { + public init(config: Config = Config(), + signalTracker: SignalTracker? = nil, + delegate: PitchEngineDelegate? = nil) { bufferSize = config.bufferSize - estimator = EstimationFactory.create(config.estimationStrategy) + + let factory = EstimationFactory() + estimator = factory.create(config.estimationStrategy) if let signalTracker = signalTracker { self.signalTracker = signalTracker @@ -55,7 +58,7 @@ public class PitchEngine { } } - queue = DispatchQueue(label: "BeethovenQueue", attributes: []) + self.queue = DispatchQueue(label: "BeethovenQueue", attributes: []) self.signalTracker.delegate = self self.delegate = delegate } @@ -84,8 +87,8 @@ public class PitchEngine { guard let weakSelf = self else { return } guard granted else { - weakSelf.delegate?.pitchEngineDidReceiveError(weakSelf, - error: PitchEngineError.recordPermissionDenied as Error) + weakSelf.delegate?.pitchEngine(weakSelf, + didReceiveError: Error.recordPermissionDenied) return } @@ -93,8 +96,6 @@ public class PitchEngine { weakSelf.activate() } } - default: - break } } @@ -108,7 +109,7 @@ public class PitchEngine { try signalTracker.start() active = true } catch { - delegate?.pitchEngineDidReceiveError(self, error: error) + delegate?.pitchEngine(self, didReceiveError: error) } } } @@ -116,25 +117,27 @@ public class PitchEngine { // MARK: - SignalTrackingDelegate extension PitchEngine: SignalTrackerDelegate { - public func signalTracker(_ signalTracker: SignalTracker, - didReceiveBuffer buffer: AVAudioPCMBuffer, atTime time: AVAudioTime) { + didReceiveBuffer buffer: AVAudioPCMBuffer, + atTime time: AVAudioTime) { queue.async { [weak self] in - guard let weakSelf = self else { return } + guard let `self` = self else { return } do { - let transformedBuffer = try weakSelf.estimator.transformer.transform(buffer: buffer) - let frequency = try weakSelf.estimator.estimateFrequency( + let transformedBuffer = try self.estimator.transformer.transform(buffer: buffer) + let frequency = try self.estimator.estimateFrequency( sampleRate: Float(time.sampleRate), buffer: transformedBuffer) let pitch = try Pitch(frequency: Double(frequency)) - DispatchQueue.main.async { - weakSelf.delegate?.pitchEngineDidReceivePitch(weakSelf, pitch: pitch) + DispatchQueue.main.async { [weak self] in + guard let `self` = self else { return } + self.delegate?.pitchEngine(self, didReceivePitch: pitch) } } catch { - DispatchQueue.main.async { - weakSelf.delegate?.pitchEngineDidReceiveError(weakSelf, error: error) + DispatchQueue.main.async { [weak self] in + guard let `self` = self else { return } + self.delegate?.pitchEngine(self, didReceiveError: error) } } } diff --git a/Source/SignalTracking/SignalTracker.swift b/Source/SignalTracking/SignalTracker.swift index a6ae17c..6e7e374 100644 --- a/Source/SignalTracking/SignalTracker.swift +++ b/Source/SignalTracking/SignalTracker.swift @@ -2,9 +2,8 @@ import AVFoundation public protocol SignalTrackerDelegate: class { func signalTracker(_ signalTracker: SignalTracker, - didReceiveBuffer buffer: AVAudioPCMBuffer, - atTime time: AVAudioTime) - + didReceiveBuffer buffer: AVAudioPCMBuffer, + atTime time: AVAudioTime) func signalTrackerWentBelowLevelThreshold(_ signalTracker: SignalTracker) } diff --git a/Source/SignalTracking/Units/InputSignalTracker.swift b/Source/SignalTracking/Units/InputSignalTracker.swift index 3b911e3..635d3bc 100644 --- a/Source/SignalTracking/Units/InputSignalTracker.swift +++ b/Source/SignalTracking/Units/InputSignalTracker.swift @@ -4,32 +4,27 @@ public enum InputSignalTrackerError: Error { case inputNodeMissing } -class InputSignalTracker: SignalTracker { - +final class InputSignalTracker: SignalTracker { weak var delegate: SignalTrackerDelegate? var levelThreshold: Float? - fileprivate let bufferSize: AVAudioFrameCount - fileprivate var audioChannel: AVCaptureAudioChannel? - fileprivate let captureSession = AVCaptureSession() - fileprivate var audioEngine: AVAudioEngine? - fileprivate let session = AVAudioSession.sharedInstance() - fileprivate let bus = 0 + private let bufferSize: AVAudioFrameCount + private var audioChannel: AVCaptureAudioChannel? + private let captureSession = AVCaptureSession() + private var audioEngine: AVAudioEngine? + private let session = AVAudioSession.sharedInstance() + private let bus = 0 var peakLevel: Float? { - get { - return audioChannel?.peakHoldLevel - } + return audioChannel?.peakHoldLevel } var averageLevel: Float? { - get { - return audioChannel?.averagePowerLevel - } + return audioChannel?.averagePowerLevel } var mode: SignalTrackerMode { - get { return .record } + return .record } // MARK: - Initialization @@ -38,7 +33,6 @@ class InputSignalTracker: SignalTracker { delegate: SignalTrackerDelegate? = nil) { self.bufferSize = bufferSize self.delegate = delegate - setupAudio() } @@ -88,18 +82,18 @@ class InputSignalTracker: SignalTracker { captureSession.stopRunning() } - fileprivate func setupAudio() { + private func setupAudio() { do { - let audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) - let audioCaptureInput = try AVCaptureDeviceInput(device: audioDevice) + let audioDevice = AVCaptureDevice.default(for: AVMediaType.audio) + let audioCaptureInput = try AVCaptureDeviceInput(device: audioDevice!) captureSession.addInput(audioCaptureInput) let audioOutput = AVCaptureAudioDataOutput() captureSession.addOutput(audioOutput) - let connection = audioOutput.connections[0] as? AVCaptureConnection - audioChannel = connection?.audioChannels[0] as? AVCaptureAudioChannel + let connection = audioOutput.connections[0] + audioChannel = connection.audioChannels[0] } catch {} } } diff --git a/Source/SignalTracking/Units/OutputSignalTracker.swift b/Source/SignalTracking/Units/OutputSignalTracker.swift index 9d6bcc2..89e7b34 100644 --- a/Source/SignalTracking/Units/OutputSignalTracker.swift +++ b/Source/SignalTracking/Units/OutputSignalTracker.swift @@ -1,32 +1,31 @@ import AVFoundation -class OutputSignalTracker: SignalTracker { - +final class OutputSignalTracker: SignalTracker { weak var delegate: SignalTrackerDelegate? var levelThreshold: Float? - fileprivate let bufferSize: AVAudioFrameCount - fileprivate let audioUrl: URL - - fileprivate var audioEngine: AVAudioEngine! - fileprivate var audioPlayer: AVAudioPlayerNode! - fileprivate let bus = 0 + private let bufferSize: AVAudioFrameCount + private let audioUrl: URL + private var audioEngine: AVAudioEngine! + private var audioPlayer: AVAudioPlayerNode! + private let bus = 0 var peakLevel: Float? { - get { return 0.0 } + return 0.0 } var averageLevel: Float? { - get { return 0.0 } + return 0.0 } - + var mode: SignalTrackerMode { - get { return .playback } + return .playback } // MARK: - Initialization - required init(audioUrl: URL, bufferSize: AVAudioFrameCount = 2048, + required init(audioUrl: URL, + bufferSize: AVAudioFrameCount = 2048, delegate: SignalTrackerDelegate? = nil) { self.audioUrl = audioUrl self.bufferSize = bufferSize @@ -48,9 +47,7 @@ class OutputSignalTracker: SignalTracker { audioEngine.connect(audioPlayer, to: audioEngine.outputNode, format: audioFile.processingFormat) audioPlayer.scheduleFile(audioFile, at: nil, completionHandler: nil) - audioEngine.outputNode.installTap(onBus: bus, bufferSize: bufferSize, format: nil) { - buffer, time in - + audioEngine.outputNode.installTap(onBus: bus, bufferSize: bufferSize, format: nil) { buffer, time in DispatchQueue.main.async { self.delegate?.signalTracker(self, didReceiveBuffer: buffer, atTime: time) } diff --git a/Source/SignalTracking/Units/SimulatorSignalTracker.swift b/Source/SignalTracking/Units/SimulatorSignalTracker.swift index a33e7b2..f7d129e 100644 --- a/Source/SignalTracking/Units/SimulatorSignalTracker.swift +++ b/Source/SignalTracking/Units/SimulatorSignalTracker.swift @@ -29,23 +29,18 @@ import AVFoundation * #endif * */ -public class SimulatorSignalTracker: SignalTracker { +public final class SimulatorSignalTracker: SignalTracker { + private static let sampleRate = 8000.0 + private static let sampleCount = 1024 public var mode: SignalTrackerMode = .record - public var levelThreshold: Float? - public var peakLevel: Float? - public var averageLevel: Float? - public weak var delegate: SignalTrackerDelegate? - private var frequencies: [Double]? - private var delay: Int - - private static let sampleRate = 8000.0 - private static let sampleCount = 1024 + private let frequencies: [Double]? + private let delay: Int public init(delegate: SignalTrackerDelegate? = nil, frequencies: [Double]? = nil, delayMs: Int = 0) { self.delegate = delegate @@ -57,46 +52,49 @@ public class SimulatorSignalTracker: SignalTracker { guard let frequencies = self.frequencies else { return } let time = AVAudioTime(sampleTime: 0, atRate: SimulatorSignalTracker.sampleRate) - var i = 0 for frequency in frequencies { let buffer = createPCMBuffer(frequency) + if i == 0 { DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(50), execute: { self.delegate?.signalTracker(self, didReceiveBuffer: buffer, atTime: time) }) - } else { DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(delay * i), execute: { self.delegate?.signalTracker(self, didReceiveBuffer: buffer, atTime: time) }) } + i += 1 } + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(delay * i), execute: { self.delegate?.signalTrackerWentBelowLevelThreshold(self) }) } - public func stop() { - } + public func stop() {} private func createPCMBuffer(_ frequency: Double) -> AVAudioPCMBuffer { let format = AVAudioFormat(standardFormatWithSampleRate: SimulatorSignalTracker.sampleRate, channels: 1) - let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(SimulatorSignalTracker.sampleCount)) + let buffer = AVAudioPCMBuffer( + pcmFormat: format!, + frameCapacity: AVAudioFrameCount(SimulatorSignalTracker.sampleCount) + ) - if let channelData = buffer.floatChannelData { - let velocity = Float32(2.0 * M_PI * frequency / SimulatorSignalTracker.sampleRate) + if let channelData = buffer?.floatChannelData { + let velocity = Float32(2.0 * .pi * frequency / SimulatorSignalTracker.sampleRate) for i in 0.. Buffer { let frameCount = buffer.frameLength let log2n = UInt(round(log2(Double(frameCount)))) diff --git a/Source/Transform/Strategies/SimpleTransformer.swift b/Source/Transform/Strategies/SimpleTransformer.swift index f59f529..58ca713 100644 --- a/Source/Transform/Strategies/SimpleTransformer.swift +++ b/Source/Transform/Strategies/SimpleTransformer.swift @@ -1,14 +1,13 @@ import AVFoundation -struct SimpleTransformer: Transformer { - +final class SimpleTransformer: Transformer { enum SimpleTransformerError: Error { - case FloatChannelDataIsNil + case floatChannelDataIsNil } func transform(buffer: AVAudioPCMBuffer) throws -> Buffer { guard let pointer = buffer.floatChannelData else { - throw SimpleTransformerError.FloatChannelDataIsNil + throw SimpleTransformerError.floatChannelDataIsNil } let elements = Array.fromUnsafePointer(pointer.pointee, count:Int(buffer.frameLength)) diff --git a/Source/Transform/Strategies/YINTransformer.swift b/Source/Transform/Strategies/YINTransformer.swift index 7498ac5..61186eb 100644 --- a/Source/Transform/Strategies/YINTransformer.swift +++ b/Source/Transform/Strategies/YINTransformer.swift @@ -10,12 +10,10 @@ import Foundation import AVFoundation -struct YINTransformer: Transformer { - +final class YINTransformer: Transformer { func transform(buffer: AVAudioPCMBuffer) throws -> Buffer { let buffer = try SimpleTransformer().transform(buffer: buffer) let diffElements = YINUtil.differenceA(buffer: buffer.elements) - return Buffer(elements: diffElements) } } diff --git a/Tests/Spec/ConfigSpec.swift b/Tests/Spec/ConfigSpec.swift index 63bd8aa..0df8cd3 100644 --- a/Tests/Spec/ConfigSpec.swift +++ b/Tests/Spec/ConfigSpec.swift @@ -2,8 +2,7 @@ import Quick import Nimble -class ConfigSpec: QuickSpec { - +final class ConfigSpec: QuickSpec { override func spec() { describe("Config") { var config: Config! @@ -14,7 +13,7 @@ class ConfigSpec: QuickSpec { expect(config.bufferSize).to(equal(4096)) expect(config.estimationStrategy).to(equal(EstimationStrategy.yin)) - expect(config.audioURL).to(beNil()) + expect(config.audioUrl).to(beNil()) } } } diff --git a/Tests/Spec/Estimation/EstimationFactorySpec.swift b/Tests/Spec/Estimation/EstimationFactorySpec.swift index 956952a..00a54a9 100644 --- a/Tests/Spec/Estimation/EstimationFactorySpec.swift +++ b/Tests/Spec/Estimation/EstimationFactorySpec.swift @@ -2,41 +2,42 @@ import Quick import Nimble -class EstimationFactorySpec: QuickSpec { - +final class EstimationFactorySpec: QuickSpec { override func spec() { describe("EstimationFactory") { + let factory = EstimationFactory() + describe(".create") { it("creates QuadradicEstimator") { - expect(EstimationFactory.create(.quadradic) is QuadradicEstimator).to(beTrue()) + expect(factory.create(.quadradic) is QuadradicEstimator).to(beTrue()) } it("creates Barycentric") { - expect(EstimationFactory.create(.barycentric) is BarycentricEstimator).to(beTrue()) + expect(factory.create(.barycentric) is BarycentricEstimator).to(beTrue()) } it("creates QuinnsFirst") { - expect(EstimationFactory.create(.quinnsFirst) is QuinnsFirstEstimator).to(beTrue()) + expect(factory.create(.quinnsFirst) is QuinnsFirstEstimator).to(beTrue()) } it("creates QuinnsSecond") { - expect(EstimationFactory.create(.quinnsSecond) is QuinnsSecondEstimator).to(beTrue()) + expect(factory.create(.quinnsSecond) is QuinnsSecondEstimator).to(beTrue()) } it("creates Jains") { - expect(EstimationFactory.create(.jains) is JainsEstimator).to(beTrue()) + expect(factory.create(.jains) is JainsEstimator).to(beTrue()) } it("creates HPS") { - expect(EstimationFactory.create(.hps) is HPSEstimator).to(beTrue()) + expect(factory.create(.hps) is HPSEstimator).to(beTrue()) } it("creates YIN") { - expect(EstimationFactory.create(.yin) is YINEstimator).to(beTrue()) + expect(factory.create(.yin) is YINEstimator).to(beTrue()) } it("creates MaxValue") { - expect(EstimationFactory.create(.maxValue) is MaxValueEstimator).to(beTrue()) + expect(factory.create(.maxValue) is MaxValueEstimator).to(beTrue()) } } } diff --git a/Tests/Spec/Estimation/EstimatorSpec.swift b/Tests/Spec/Estimation/EstimatorSpec.swift index 141812f..c2790d2 100644 --- a/Tests/Spec/Estimation/EstimatorSpec.swift +++ b/Tests/Spec/Estimation/EstimatorSpec.swift @@ -2,8 +2,7 @@ import Quick import Nimble -class EstimatorSpec: QuickSpec { - +final class EstimatorSpec: QuickSpec { override func spec() { describe("Estimator") { var estimator: Estimator! diff --git a/Tests/Spec/Extensions/ArrayExtensionsSpec.swift b/Tests/Spec/Extensions/ArrayExtensionsSpec.swift index d70f3de..0a6dca4 100644 --- a/Tests/Spec/Extensions/ArrayExtensionsSpec.swift +++ b/Tests/Spec/Extensions/ArrayExtensionsSpec.swift @@ -2,8 +2,7 @@ import Quick import Nimble -class ArrayExtensionsSpec: QuickSpec { - +final class ArrayExtensionsSpec: QuickSpec { override func spec() { describe("Array+Extensions") { diff --git a/Tests/Spec/Library/BufferSpec.swift b/Tests/Spec/Library/BufferSpec.swift index b0be6d9..e6bd59d 100644 --- a/Tests/Spec/Library/BufferSpec.swift +++ b/Tests/Spec/Library/BufferSpec.swift @@ -2,8 +2,7 @@ import Quick import Nimble -class BufferSpec: QuickSpec { - +final class BufferSpec: QuickSpec { override func spec() { describe("Buffer") { var buffer: Buffer! diff --git a/Tests/Spec/Transform/Strategies/FFTTransformerSpec.swift b/Tests/Spec/Transform/Strategies/FFTTransformerSpec.swift index ad1ac9d..cdcd2c5 100644 --- a/Tests/Spec/Transform/Strategies/FFTTransformerSpec.swift +++ b/Tests/Spec/Transform/Strategies/FFTTransformerSpec.swift @@ -3,8 +3,7 @@ import Quick import Nimble import Accelerate -class FFTTransformerSpec: QuickSpec { - +final class FFTTransformerSpec: QuickSpec { override func spec() { describe("FFTTransformer") { var transformer: FFTTransformer!