Skip to content

Instantly share code, notes, and snippets.

//
// SpectralAnalyzer.swift
// Episode V
//
// Created by Mike Muszynski on 3/19/19.
// Copyright © 2019 Mike Muszynski. All rights reserved.
//
import Foundation
import AudioToolbox
class CenteredClipView: NSClipView {
override func constrainBoundsRect(_ proposedBounds: NSRect) -> NSRect {
var rect = super.constrainBoundsRect(proposedBounds)
if let containerView = self.documentView {
if (rect.size.width > containerView.frame.size.width) {
rect.origin.x = (containerView.frame.width - rect.width) / 2
}
if(rect.size.height > containerView.frame.size.height) {
//Creating the view
override func mouseDown(with event: NSEvent) {
let click = event.locationInWindow
let point = self.convert(click, from: nil)
self.addDot(at: point)
NotificationCenter.default.post(name: .pointsChanged, object: nil)
}
func addDot(at locationInView: CGPoint) {
//
// FFTAnalyzer.swift
// FFTVisualizer2018
//
// Created by Mike Muszynski on 2/12/18.
// Copyright © 2018 Mike Muszynski. All rights reserved.
//
import Cocoa
import AudioToolbox
var waveVisualizerTrackingArea: NSTrackingArea!
var fftVisuzalizerTrackingArea: NSTrackingArea!
func setupTracking() {
waveVisualizerTrackingArea = NSTrackingArea(rect: waveVisualizerBox.frame, options: [.activeInActiveApp, .mouseMoved], owner: self, userInfo: nil)
fftVisuzalizerTrackingArea = NSTrackingArea(rect: fftVisualizerBox.frame, options: [.activeInActiveApp, .mouseMoved], owner: self, userInfo: nil)
self.view.addTrackingArea(waveVisualizerTrackingArea)
self.view.addTrackingArea(fftVisuzalizerTrackingArea)
}
override func mouseMoved(with event: NSEvent) {
/// Creates an array of values to display
///
/// Averages values and performs in batches in the background
func resetDrawValues() {
guard values.count > 0 else {
print("load data first")
return
}
drawValues = []
public override func draw(_ dirtyRect: NSRect) {
for location in Int(dirtyRect.origin.x)..<Int(dirtyRect.origin.x + dirtyRect.size.width) {
let colorBox = NSBezierPath(rect: NSRect(x: CGFloat(location), y:0, width: 2.0, height: self.bounds.size.height))
var alpha: CGFloat = 1.0
if location < drawValues.count {
let locationPower = drawValues[location]
guard let locationmax = drawValues.max() else {
fatalError()
}
//Version 1, very slow
_powerData = [Float](repeatElement(0, count: loadedAudioData.count))
for value in loadedAudioData.enumerated() {
let square = value.element * value.element
_powerData![value.offset] = square
}
//Version 2, much faster
_powerData = loadedAudioData.map({ (value) in
let view = MusicStaffView()
let root = MusicPitch(name: .g, accidental: .natural, octave: 3)
let scale = try! MusicScale(root: root, mode: .melodicMinor, direction: .up)
let notes = scale.map { MusicNote(pitch: $0, rhythm: (arc4random() % 2) == 0 ? .quarter : .half) }
view.elements = [MusicClef.treble] + notes + [MusicStaffViewBarLine.final]
extension MusicNote: MusicStaffViewElement {
public func direction(in clef: MusicClef) -> MusicStaffViewElementDirection {
let offset = clef.offsetForPitch(named: self.pitch.name, octave: self.pitch.octave)
return offset < 0 ? .up : .down
}
public func offset(in clef: MusicClef) -> Int {
return clef.offsetForPitch(named: self.pitch.name, octave: self.pitch.octave)
}