From 731f3e7a382293776cde53dbea45f1bced30fb40 Mon Sep 17 00:00:00 2001 From: nodeful <romankisilo@gmail.com> Date: Sun, 17 May 2020 22:53:33 +0100 Subject: [PATCH] released version v0.2.0 --- native/app/Source/Application.swift | 8 +- .../Source/Audio/Outputs/AUGraphOutput.swift | 359 ------------------ native/app/Source/Audio/Volume/Volume.swift | 21 +- .../Source/Audio/Volume/VolumeDataBus.swift | 13 + .../app/Source/Audio/Volume/VolumeState.swift | 42 +- native/app/Source/Constants.swift | 4 +- .../app/Source/Extensions/AudioDevice.swift | 9 + native/app/Source/Scripts/install_driver.sh | 20 +- native/app/Source/Scripts/uninstall_driver.sh | 2 +- native/app/eqMac.xcodeproj/project.pbxproj | 8 +- native/app/update/CHANGELOG.md | 8 + native/app/update/eqMac.html | 9 + native/app/update/update.xml | 18 +- ui/package.json | 2 +- .../basic-equalizer.component.ts | 1 + 15 files changed, 116 insertions(+), 408 deletions(-) delete mode 100644 native/app/Source/Audio/Outputs/AUGraphOutput.swift diff --git a/native/app/Source/Application.swift b/native/app/Source/Application.swift index 68510950..83781c87 100644 --- a/native/app/Source/Application.swift +++ b/native/app/Source/Application.swift @@ -194,6 +194,8 @@ class Application { } } + static var ignoreNextVolumeEvent = false + private static func setupDeviceEvents () { AudioDeviceEvents.on(.outputChanged) { device in if device.isHardware { @@ -218,7 +220,7 @@ class Application { } } AudioDeviceEvents.on(.muteChanged, onDevice: Driver.device!) { - selectedDevice.mute = Driver.device!.mute + Application.dispatchAction(VolumeAction.setMuted(Driver.device!.mute)) } AudioDeviceEvents.onDeviceListChanged { list in @@ -390,9 +392,7 @@ class Application { Application.dispatchAction(VolumeAction.setGain(newGain, false)) } } - - static var ignoreNextVolumeEvent = false - + private static func killEngine () { engine = nil } diff --git a/native/app/Source/Audio/Outputs/AUGraphOutput.swift b/native/app/Source/Audio/Outputs/AUGraphOutput.swift deleted file mode 100644 index e401f240..00000000 --- a/native/app/Source/Audio/Outputs/AUGraphOutput.swift +++ /dev/null @@ -1,359 +0,0 @@ -//// -//// Output.swift -//// eqMac -//// -//// Created by Roman Kisil on 05/11/2018. -//// Copyright © 2018 Roman Kisil. All rights reserved. -//// -// -//import Foundation -//import AMCoreAudio -//import SwiftyUserDefaults -//import AudioKit -//import EmitterKit -// -//class Output { -// static var allowedDevices: [AudioDevice] { -// return AudioDevice.allOutputDevices() -// .filter({ device in -// if let uid = device.uid { -// if (uid == Constants.PASSTHROUGH_DEVICE_UID || Constants.LEGACY_DRIVER_UIDS.contains(uid)) { -// return false -// } -// } -// return device.transportType != nil && Constants.SUPPORTED_TRANSPORT_TYPES.contains(device.transportType!) -// }) -// } -// -// let outputRenderCallback: AURenderCallback = { -// (inRefCon: UnsafeMutableRawPointer, -// ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, -// inTimeStamp: UnsafePointer<AudioTimeStamp>, -// inBusNumber: UInt32, -// inNumberFrames: UInt32, -// ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus in -// -// let abl = UnsafeMutableAudioBufferListPointer(ioData)! -// let output = Unmanaged<Output>.fromOpaque(inRefCon).takeUnretainedValue() -// let engine: Engine! = output.engine! -// var inTS = AudioTimeStamp() -// var outTS = AudioTimeStamp() -// let inputDevice = Driver.device! -// if engine.firstInputTime < 0 { -// makeBufferSilent(abl) -// return noErr -// } -// -// if AudioDeviceGetCurrentTime(inputDevice.id, &inTS) != noErr { -// makeBufferSilent(abl) -// return noErr -// } -// -// if AudioDeviceGetCurrentTime(output.device.id, &outTS) != noErr { -// makeBufferSilent(abl) -// return noErr -// } -// -// let rate = inTS.mRateScalar / outTS.mRateScalar -// if let err = checkErr(AudioUnitSetParameter(output.varispeedUnit!, kVarispeedParam_PlaybackRate, kAudioUnitScope_Global, 0, AudioUnitParameterValue(rate), 0)) { -// return err -// } -// -// let sampleTime = inTimeStamp.pointee.mSampleTime -// if output.firstOutputTime < 0 { -// output.firstOutputTime = sampleTime -// let delta = engine.firstInputTime - output.firstOutputTime -// output.computeThruOffset(inputDevice: inputDevice, outputDevice: output.device) -// -// if delta < 0 { -// output.inToOutSampleOffset -= delta -// } else { -// output.inToOutSampleOffset = -delta + output.inToOutSampleOffset -// } -// -// makeBufferSilent(abl) -// return noErr -// } -// -// let err = engine.ringBuffer.fetch(ioData!, framesToRead: inNumberFrames, startRead: Int64(sampleTime - output.inToOutSampleOffset)) -// if err != CARingBufferError.noError { -// makeBufferSilent(abl) -// var bufferStartTime: SampleTime = 0 -// var bufferEndTime: SampleTime = 0 -// _ = engine.ringBuffer.getTimeBounds(startTime: &bufferStartTime, endTime: &bufferEndTime) -// output.inToOutSampleOffset = sampleTime - bufferStartTime.doubleValue -// return noErr -// } -// -// return noErr -// } -// -// var device: AudioDevice! -// var engine: Engine! -// -// var graph: AUGraph? = nil -// var varispeedNode: AUNode = 0 -// var varispeedUnit: AudioUnit? = nil -// var formatNode: AUNode = 0 -// var formatUnit: AudioUnit? = nil -// var outputNode: AUNode = 0 -// var outputUnit: AudioUnit? = nil -// -// var firstOutputTime: Double = -1 -// var inToOutSampleOffset: Double = 0 -// -// let deviceChanged = EmitterKit.Event<AudioDevice>() -// -// init(device: AudioDevice!, engine: Engine!) { -// Console.log("Creating Output for Device: " + device.name) -// self.device = device -// self.engine = engine -// -// computeThruOffset(inputDevice: Driver.device!, outputDevice: device) -// -// // Setup Graph containing Varispeed Unit & Default Output Unit -// Console.log("Setting up AUGraph") -// if let _ = checkErr(setupGraph()) { -// exit(1) -// } -// -// Console.log("Setting up Buffers") -// if let _ = checkErr(setupBuffers()) { -// exit(1) -// } -// -// Console.log("Connecting Nodes") -// // the varispeed unit should only be conected after the input and output formats have been set -// if let _ = checkErr(AUGraphConnectNodeInput(graph!, varispeedNode, 0, formatNode, 0)) { -// exit(1) -// } -// -// if let _ = checkErr(AUGraphConnectNodeInput(graph!, formatNode, 0, outputNode, 0)) { -// exit(1) -// } -// -// Console.log("Initializing AUGraph") -// if let _ = checkErr(AUGraphInitialize(graph!)) { -// exit(1) -// } -// -// // Add latency between the two devices -// computeThruOffset(inputDevice: Driver.device!, outputDevice: device) -// -// CAShow(UnsafeMutablePointer(graph!)) -// -// start() -// -// } -// -// private func setupGraph () -> OSStatus { -// // Make a New Graph -// Console.log("Creating new AUGraph") -// if let err = checkErr(NewAUGraph(&graph)) { -// return err -// } -// -// Console.log("Openning AUGraph") -// // Open the Graph, AudioUnits are opened but not initialized -// if let err = checkErr(AUGraphOpen(graph!)) { -// return err -// } -// -// Console.log("Making AUGraph") -// if let err = checkErr(makeGraph()) { -// return err -// } -// -// Console.log("Setting Output Device") -// if let err = checkErr(setOutputDeviceAsCurrent()) { -// return err -// } -// -// // Tell the output unit not to reset timestamps -// // Otherwise sample rate changes will cause sync los -// var startAtZero : UInt32 = 0 -// if let err = checkErr(AudioUnitSetProperty(outputUnit!, kAudioOutputUnitProperty_StartTimestampsAtZero, -// kAudioUnitScope_Global, 0, &startAtZero, UInt32(MemoryLayout<UInt32>.size))) { -// return err -// } -// -// -// var output = AURenderCallbackStruct( -// inputProc: outputRenderCallback, -// inputProcRefCon: UnsafeMutableRawPointer(Unmanaged<Output>.passUnretained(self).toOpaque()) -// ) -// -// if let err = checkErr(AudioUnitSetProperty(varispeedUnit!, kAudioUnitProperty_SetRenderCallback, -// kAudioUnitScope_Input, 0, &output, UInt32(MemoryLayout<AURenderCallbackStruct>.size))) { -// return err -// } -// return noErr -// } -// -// private func makeGraph() -> OSStatus { -// var varispeedDesc = AudioComponentDescription() -// var formatDesc = AudioComponentDescription() -// var outDesc = AudioComponentDescription() -// -// // Q:Why do we need a varispeed unit? -// // A:If the input device and the output device are running at different sample rates -// // we will need to move the data coming to the graph slower/faster to avoid a pitch change. -// varispeedDesc.componentType = kAudioUnitType_FormatConverter -// varispeedDesc.componentSubType = kAudioUnitSubType_Varispeed -// varispeedDesc.componentManufacturer = kAudioUnitManufacturer_Apple -// varispeedDesc.componentFlags = 0 -// varispeedDesc.componentFlagsMask = 0 -// -// formatDesc.componentType = kAudioUnitType_FormatConverter -// formatDesc.componentSubType = kAudioUnitSubType_AUConverter -// formatDesc.componentManufacturer = kAudioUnitManufacturer_Apple -// formatDesc.componentFlags = 0 -// formatDesc.componentFlagsMask = 0 -// -// outDesc.componentType = kAudioUnitType_Output -// outDesc.componentSubType = kAudioUnitSubType_HALOutput -// outDesc.componentManufacturer = kAudioUnitManufacturer_Apple -// outDesc.componentFlags = 0 -// outDesc.componentFlagsMask = 0 -// -// ////////////////////////// -// /// MAKE NODES -// // This creates a node in the graph that is an AudioUnit, using -// // the supplied ComponentDescription to find and open that unit -// if let err = checkErr(AUGraphAddNode(graph!, &varispeedDesc, &varispeedNode)) { -// return err -// } -// -// if let err = checkErr(AUGraphAddNode(graph!, &formatDesc, &formatNode)) { -// return err -// } -// -// if let err = checkErr(AUGraphAddNode(graph!, &outDesc, &outputNode)) { -// return err -// } -// -// // Get Audio Units from AUGraph node -// if let err = checkErr(AUGraphNodeInfo(graph!, varispeedNode, nil, &varispeedUnit)) { -// return err -// } -// -// if let err = checkErr(AUGraphNodeInfo(graph!, formatNode, nil, &formatUnit)) { -// return err -// } -// -// if let err = checkErr(AUGraphNodeInfo(graph!, outputNode, nil, &outputUnit)) { -// return err -// } -// -// // don't connect nodes until the varispeed unit has input and output formats set -// -// return noErr -// } -// -// func setOutputDeviceAsCurrent() -> OSStatus { -// var id = device.id -// // Set the Current Device to the Default Output Unit. -// return AudioUnitSetProperty(outputUnit!, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Output, 0, -// &id, UInt32(MemoryLayout<AudioDeviceID>.size)) -// } -// -// func setupBuffers() -> OSStatus { -// let input = Driver.device! -// let inputUnit = engine.engine.inputNode.audioUnit! -// -// var inputFormat = AudioStreamBasicDescription() -// // Get the Input Format -// var propertySize = UInt32(MemoryLayout<AudioStreamBasicDescription>.size); -// if let err = checkErr(AudioUnitGetProperty(inputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inputFormat, &propertySize)) { -// return err; -// } -// -// var outputFormat = inputFormat -// outputFormat.mSampleRate = device.nominalSampleRate()! -// outputFormat.mChannelsPerFrame = ((input.channels(direction: .recording) < device.channels(direction: .playback)) ? input.channels(direction: .recording) :device.channels(direction: .playback)) -// -//// inputFormat.mFormatFlags = 9 -//// outputFormat.mFormatFlags = 9 -// -// //WIRE AudioStreamBasicDescription(mSampleRate: 44100.0, mFormatID: 1819304813, mFormatFlags: 41, mBytesPerPacket: 4, mFramesPerPacket: 1, mBytesPerFrame: 4, mChannelsPerFrame: 2, mBitsPerChannel: 32, mReserved: 0) -// //BT AudioStreamBasicDescription(mSampleRate: 48000.0, mFormatID: 1819304813, mFormatFlags: 41, mBytesPerPacket: 4, mFramesPerPacket: 1, mBytesPerFrame: 4, mChannelsPerFrame: 2, mBitsPerChannel: 32, mReserved: 0) -// Console.log(inputFormat) -// Console.log(outputFormat) -// -// if let err = checkErr(AudioUnitSetProperty(varispeedUnit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inputFormat, propertySize)) { -// return err -// } -// -// if let err = checkErr(AudioUnitSetProperty(varispeedUnit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &outputFormat, propertySize)) { -// return err -// } -//// -//// if let err = checkErr(AudioUnitSetProperty(formatUnit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputFormat, propertySize)) { -//// return err -//// } -//// -//// if let err = checkErr(AudioUnitSetProperty(formatUnit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &outputFormat, propertySize)) { -//// return err -//// } -//// -// if let err = checkErr(AudioUnitSetProperty(outputUnit!, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputFormat, propertySize)) { -// return err -// } -// -// return noErr -// -// } -// -// // Alloc rin -// -// func computeThruOffset(inputDevice : AudioDevice, -// outputDevice: AudioDevice) { -// let inputOffset = inputDevice.safetyOffset(direction: .recording) -// let outputOffset = outputDevice.safetyOffset(direction: .playback) -// let inputBuffer = inputDevice.bufferFrameSize(direction: .recording) -// let outputBuffer = outputDevice.bufferFrameSize(direction: .playback) -// inToOutSampleOffset = Double(inputOffset! + outputOffset! + inputBuffer + outputBuffer) -// } -// -// deinit { -// cleanup() -// } -// -// private func cleanup () { -// stop() -// } -// -// func start() { -// if isRunning { -// return -// } -// -// if let _ = checkErr(AUGraphStart(graph!)) { -// return -// } -// -// // reset sample times -// firstOutputTime = -1 -// } -// -// func stop() { -// if !isRunning { -// return -// } -// -// if let _ = checkErr(AUGraphStop(graph!)) { -// return -// } -// firstOutputTime = -1 -// } -// -// var isRunning: Bool { -// var running : DarwinBoolean = false -// -// if let _ = checkErr(AUGraphIsRunning(graph!, &running)) { -// return false -// } -// -// return running.boolValue -// } -//} diff --git a/native/app/Source/Audio/Volume/Volume.swift b/native/app/Source/Audio/Volume/Volume.swift index c91fe756..43ecb78d 100644 --- a/native/app/Source/Audio/Volume/Volume.swift +++ b/native/app/Source/Audio/Volume/Volume.swift @@ -16,7 +16,8 @@ class Volume: StoreSubscriber { // MARK: - Events var gainChanged = EmitterKit.Event<Double>() var balanceChanged = EmitterKit.Event<Double>() - + var mutedChanged = EmitterKit.Event<Bool>() + // MARK: - Properties var gain: Double = 1 { didSet { @@ -71,7 +72,7 @@ class Volume: StoreSubscriber { newRightGain = gain * Utilities.mapValue(value: Double(balance), inMin: 0, inMax: -1, outMin: 1, outMax: 0) } } - + Driver.device!.setVirtualMasterVolume(Float32(gain), direction: .playback) } @@ -83,6 +84,18 @@ class Volume: StoreSubscriber { } } + var muted: Bool = false { + didSet { + if (muted) { + leftGain = 0 + rightGain = 0 + } else { + (gain = gain) + } + mutedChanged.emit(muted) + } + } + var balance: Double = 0 { didSet { if (balance > 1) { @@ -136,6 +149,10 @@ class Volume: StoreSubscriber { gain = state.gain } } + + if (state.muted != muted) { + muted = state.muted + } } // MARK: - Initialization diff --git a/native/app/Source/Audio/Volume/VolumeDataBus.swift b/native/app/Source/Audio/Volume/VolumeDataBus.swift index f80cd22e..66df95d9 100644 --- a/native/app/Source/Audio/Volume/VolumeDataBus.swift +++ b/native/app/Source/Audio/Volume/VolumeDataBus.swift @@ -48,6 +48,19 @@ class VolumeDataBus: DataBus { return "Volume Balance has been set" } + self.on(.GET, "/muted") { _, _ in + return [ "muted": self.state.muted ] + } + + self.on(.POST, "/muted") { data, _ in + let muted = data["muted"] as? Bool + if (muted == nil) { + throw "Invalid 'muted' value, must be a boolean" + } + Application.dispatchAction(VolumeAction.setMuted(muted!)) + return "Volume mute has been set" + } + gainChangedListener = Application.volume.gainChanged.on { gain in self.send(to: "/gain", data: JSON([ "gain": gain ])) } diff --git a/native/app/Source/Audio/Volume/VolumeState.swift b/native/app/Source/Audio/Volume/VolumeState.swift index 7f63ef38..181867cf 100644 --- a/native/app/Source/Audio/Volume/VolumeState.swift +++ b/native/app/Source/Audio/Volume/VolumeState.swift @@ -11,29 +11,33 @@ import ReSwift import SwiftyUserDefaults struct VolumeState: State { - var gain: Double = 0.5 - var balance: Double = 0 - var transition: Bool = false + var gain: Double = 0.5 + var muted: Bool = false + var balance: Double = 0 + var transition: Bool = false } enum VolumeAction: Action { - case setGain(Double, Bool) - case setBalance(Double, Bool) + case setGain(Double, Bool) + case setBalance(Double, Bool) + case setMuted(Bool) } func VolumeStateReducer(action: Action, state: VolumeState?) -> VolumeState { - var state = state ?? VolumeState() - - switch action as? VolumeAction { - case .setGain(let gain, let transition)?: - state.gain = gain - state.transition = transition - case .setBalance(let balance, let transition)?: - state.balance = balance - state.transition = transition - case .none: - break - } - - return state + var state = state ?? VolumeState() + + switch action as? VolumeAction { + case .setGain(let gain, let transition)?: + state.gain = gain + state.transition = transition + case .setBalance(let balance, let transition)?: + state.balance = balance + state.transition = transition + case .setMuted(let muted)?: + state.muted = muted + case .none: + break + } + + return state } diff --git a/native/app/Source/Constants.swift b/native/app/Source/Constants.swift index f41669ed..3b2142e8 100644 --- a/native/app/Source/Constants.swift +++ b/native/app/Source/Constants.swift @@ -14,11 +14,11 @@ struct Constants { #if DEBUG static let UI_ENDPOINT_URL = URL(string: "http://localhost:4200")! -// static let UI_ENDPOINT_URL = URL(string: "https://ui-v0.eqmac.app")! +// static let UI_ENDPOINT_URL = URL(string: "https://ui-v1.eqmac.app")! static let DEBUG = true #else static let DEBUG = false - static let UI_ENDPOINT_URL = URL(string: "https://ui-v0.eqmac.app")! + static let UI_ENDPOINT_URL = URL(string: "https://ui-v1.eqmac.app")! #endif static let SENTRY_ENDPOINT = "https://afd95e4c332b4b1da4bb23b9cc66782c@sentry.io/1243254" diff --git a/native/app/Source/Extensions/AudioDevice.swift b/native/app/Source/Extensions/AudioDevice.swift index 2c8956ba..4cf3dda9 100644 --- a/native/app/Source/Extensions/AudioDevice.swift +++ b/native/app/Source/Extensions/AudioDevice.swift @@ -5,6 +5,15 @@ import CoreFoundation import EmitterKit extension AudioDevice { + + var stashedVolume: Double { + get { + return Storage.double(forKey: "stashedVolume:\(self.id)") + } + set { + Storage.set(newValue, forKey: "stashedVolume:\(self.id)") + } + } var json: [String: AnyObject] { return AudioDevice.toJSON(self) } diff --git a/native/app/Source/Scripts/install_driver.sh b/native/app/Source/Scripts/install_driver.sh index d7078ba4..dcc78bb7 100755 --- a/native/app/Source/Scripts/install_driver.sh +++ b/native/app/Source/Scripts/install_driver.sh @@ -10,20 +10,20 @@ fi DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Remove legacy drivers -kextunload /System/Library/Extensions/eqMacDriver.kext/ || true -rm -rf /System/Library/Extensions/eqMacDriver.kext/ || true +kextunload /System/Library/Extensions/eqMacDriver.kext/ &>/dev/null || true +rm -rf /System/Library/Extensions/eqMacDriver.kext/ &>/dev/null || true -kextunload /Library/Extensions/eqMacDriver.kext/ || true -rm -rf /Library/Extensions/eqMacDriver.kext/ || true +kextunload /Library/Extensions/eqMacDriver.kext/ &>/dev/null || true +rm -rf /Library/Extensions/eqMacDriver.kext/ &>/dev/null || true -kextunload /System/Library/Extensions/eqMac2Driver.kext/ || true -rm -rf /System/Library/Extensions/eqMac2Driver.kext/ || true +kextunload /System/Library/Extensions/eqMac2Driver.kext/ &>/dev/null || true +rm -rf /System/Library/Extensions/eqMac2Driver.kext/ &>/dev/null || true -kextunload /Library/Extensions/eqMac2Driver.kext/ || true -rm -rf /Library/Extensions/eqMac2Driver.kext/ || true +kextunload /Library/Extensions/eqMac2Driver.kext/ &>/dev/null || true +rm -rf /Library/Extensions/eqMac2Driver.kext/ &>/dev/null || true -touch /System/Library/Extensions || true -touch /Library/Extensions || true +touch /System/Library/Extensions &>/dev/null || true +touch /Library/Extensions &>/dev/null || true # Copy driver into Plug-Ins folder cp -f -r "$DIR/eqMac.driver" /Library/Audio/Plug-Ins/HAL/ || diff --git a/native/app/Source/Scripts/uninstall_driver.sh b/native/app/Source/Scripts/uninstall_driver.sh index eb6d7f9e..bdde0e23 100755 --- a/native/app/Source/Scripts/uninstall_driver.sh +++ b/native/app/Source/Scripts/uninstall_driver.sh @@ -7,7 +7,7 @@ if [ -n "$CI" ] && [ "$GITHUB_REPOSITORY" == "Homebrew/homebrew-cask" ]; then fi # Uninstall the new driver -rm -rf /Library/Audio/Plug-Ins/HAL/eqMac.driver/ +rm -rf /Library/Audio/Plug-Ins/HAL/eqMac.driver/ &>/dev/null || true # Restart CoreAudio coreaudiod_plist="/System/Library/LaunchDaemons/com.apple.audio.coreaudiod.plist" diff --git a/native/app/eqMac.xcodeproj/project.pbxproj b/native/app/eqMac.xcodeproj/project.pbxproj index 5f974ad3..b8608ef6 100644 --- a/native/app/eqMac.xcodeproj/project.pbxproj +++ b/native/app/eqMac.xcodeproj/project.pbxproj @@ -100,7 +100,6 @@ E0F4FD9E22888D5A00BEB0A6 /* eqMac.driver in Resources */ = {isa = PBXBuildFile; fileRef = E0F4FD9D22888D5A00BEB0A6 /* eqMac.driver */; }; E0F661711FDC38BE00252923 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0F661701FDC38B600252923 /* WebKit.framework */; }; E0F661861FDDED0C00252923 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F661851FDDED0C00252923 /* ViewController.swift */; }; - E0F6A112220D573C00D16624 /* AUGraphOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F6A111220D573C00D16624 /* AUGraphOutput.swift */; }; E0FFB703200119060003EC9E /* StatusItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0FFB702200119060003EC9E /* StatusItem.swift */; }; E0FFB705200679DD0003EC9E /* Engine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0FFB704200679DD0003EC9E /* Engine.swift */; }; /* End PBXBuildFile section */ @@ -227,7 +226,6 @@ E0F4FD9D22888D5A00BEB0A6 /* eqMac.driver */ = {isa = PBXFileReference; lastKnownFileType = folder; name = eqMac.driver; path = ../build/eqMac/Build/Products/Release/eqMac.driver; sourceTree = "<group>"; }; E0F661701FDC38B600252923 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; E0F661851FDDED0C00252923 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; - E0F6A111220D573C00D16624 /* AUGraphOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AUGraphOutput.swift; sourceTree = "<group>"; }; E0FFB702200119060003EC9E /* StatusItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItem.swift; sourceTree = "<group>"; }; E0FFB704200679DD0003EC9E /* Engine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Engine.swift; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -435,10 +433,10 @@ E095BBC22014CE19003473E9 /* Audio */ = { isa = PBXGroup; children = ( - E00C595723BBB84900C7B8B6 /* RingBuffer */, - E0AD99DA225114C600D893F7 /* Volume */, E01B1BB3235E449000CC58E5 /* Sources */, + E0AD99DA225114C600D893F7 /* Volume */, E090AD5B20A9F13E003BE5FF /* Effects */, + E00C595723BBB84900C7B8B6 /* RingBuffer */, E0AD99DB2251151F00D893F7 /* Outputs */, E02B922D219CBCD800AC130B /* AudioDeviceEvents.swift */, E057A636227032EC0019D13C /* EngineDataBus.swift */, @@ -483,7 +481,6 @@ E0AD99DB2251151F00D893F7 /* Outputs */ = { isa = PBXGroup; children = ( - E0F6A111220D573C00D16624 /* AUGraphOutput.swift */, E07CB5B021902F4F0033DA89 /* Output.swift */, E057A6502271A7DC0019D13C /* OutputsDataBus.swift */, E031E9CD23700DDF00BA6DD8 /* Outputs.swift */, @@ -883,7 +880,6 @@ E01B1BB9235E454500CC58E5 /* InputSource.swift in Sources */, E06E98D221D2E32E0041DD9C /* Popover.swift in Sources */, E07B45A620FBA4990086AA7E /* Encodable.swift in Sources */, - E0F6A112220D573C00D16624 /* AUGraphOutput.swift in Sources */, E0241AA5225E9FB700748656 /* BasicEqualizerPreset.swift in Sources */, E057A639227038B80019D13C /* Settings.swift in Sources */, E0C5629920A75BAD000902ED /* Storage.swift in Sources */, diff --git a/native/app/update/CHANGELOG.md b/native/app/update/CHANGELOG.md index f9ff6c4d..dd620e2d 100644 --- a/native/app/update/CHANGELOG.md +++ b/native/app/update/CHANGELOG.md @@ -1,5 +1,13 @@ # eqMac Changelog +## v0.2.0 +* Added optional Peak Limiter to Basic EQ +* Added Popover / Window mode switch +* Improved Window UX to match native macOS behaviour +* Checking for updates before app launches to allow people to update in case eqMac always crashed +* Allow muting on HDMI/DisplayPort devices +* Potential fix for users that don't get any sound on macOS Catalina + ## v0.1.1 * Fix instant crashed on macOS 10.14 and lower diff --git a/native/app/update/eqMac.html b/native/app/update/eqMac.html index 22c82006..7c55d471 100644 --- a/native/app/update/eqMac.html +++ b/native/app/update/eqMac.html @@ -1,4 +1,13 @@ <h1 id="eqmac-changelog">eqMac Changelog</h1> +<h2 id="v0-2-0">v0.2.0</h2> +<ul> +<li>Added optional Peak Limiter to Basic EQ</li> +<li>Added Popover / Window mode switch</li> +<li>Improved Window UX to match native macOS behaviour</li> +<li>Checking for updates before app launches to allow people to update in case eqMac always crashed</li> +<li>Allow muting on HDMI/DisplayPort devices</li> +<li>Potential fix for users that don't get any sound on macOS Catalina</li> +</ul> <h2 id="v0-1-1">v0.1.1</h2> <ul> <li>Fix instant crashed on macOS 10.14 and lower</li> diff --git a/native/app/update/update.xml b/native/app/update/update.xml index fe77fa4f..534d10da 100644 --- a/native/app/update/update.xml +++ b/native/app/update/update.xml @@ -3,9 +3,19 @@ <channel> <title>eqMac</title> <item> - <title>v0.1.1</title> - <pubDate>Wed, 29 Apr 2020 20:01:12 +0100</pubDate> - <description><![CDATA[<h1 id="eqmac-changelog">eqMac Changelog</h1> + <title>v0.2.0</title> + <pubDate>Sun, 17 May 2020 21:53:36 +0100</pubDate> + <description><![CDATA[ +<h1 id="eqmac-changelog">eqMac Changelog</h1> +<h2 id="v0-2-0">v0.2.0</h2> +<ul> +<li>Added optional Peak Limiter to Basic EQ</li> +<li>Added Popover / Window mode switch</li> +<li>Improved Window UX to match native macOS behaviour</li> +<li>Checking for updates before app launches to allow people to update in case eqMac always crashed</li> +<li>Allow muting on HDMI/DisplayPort devices</li> +<li>Potential fix for users that don't get any sound on macOS Catalina</li> +</ul> <h2 id="v0-1-1">v0.1.1</h2> <ul> <li>Fix instant crashed on macOS 10.14 and lower</li> @@ -32,7 +42,7 @@ </ul> ]]></description> <sparkle:minimumSystemVersion>10.12</sparkle:minimumSystemVersion> - <enclosure url="https://update.eqmac.app/eqMac.dmg" sparkle:version="0.1.1" sparkle:shortVersionString="v0.1.1" length="13415309" type="application/octet-stream" sparkle:edSignature="Uxrl5BE+wKFb/EcYw8gzO22T3ttK6KZUwB5GlvdSM21k7Hb75uxdswRXBYKo2aYW4VqnUav7FocUeLrUycRrCQ=="/> + <enclosure url="https://update.eqmac.app/eqMac.dmg" sparkle:version="0.2.0" sparkle:shortVersionString="v0.2.0" length="13449798" type="application/octet-stream" sparkle:edSignature="cV4hR+rcSaqk9oWBSSpv2X6IUj4xd4pJ4IOt8e9KnVAxrgd7We2UdCTenBRhGEFIwjGngv7KS20Iiqq0pKVzBA=="/> </item> </channel> </rss> \ No newline at end of file diff --git a/ui/package.json b/ui/package.json index c06d3fa3..1b2659ae 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "eqmac", - "version": "0.1.0", + "version": "1.0.0", "scripts": { "start": "ng serve", "build": "rm -rf dist/ && ng build --prod && cd dist/ && zip -r -D ui.zip * -x '*.DS_Store'", diff --git a/ui/src/app/sections/effects/equalizers/basic-equalizer/basic-equalizer.component.ts b/ui/src/app/sections/effects/equalizers/basic-equalizer/basic-equalizer.component.ts index 22daa47a..fa442c51 100644 --- a/ui/src/app/sections/effects/equalizers/basic-equalizer/basic-equalizer.component.ts +++ b/ui/src/app/sections/effects/equalizers/basic-equalizer/basic-equalizer.component.ts @@ -147,6 +147,7 @@ export class BasicEqualizerComponent extends EqualizerComponent implements OnIni manualPreset.gains = { ...this.selectedPreset.gains } } manualPreset.gains[band] = event.value + manualPreset.peakLimiter = !!this.selectedPreset.peakLimiter this.selectedPreset = manualPreset if (!event.transition) {