1
1
mirror of https://github.com/bitgapp/eqMac.git synced 2024-11-22 04:33:53 +03:00

upload new source code

This commit is contained in:
nodeful 2020-04-04 19:15:38 +01:00
parent 0650b04a34
commit ba3d98b2fb
678 changed files with 61600 additions and 10378 deletions

View File

@ -1,30 +0,0 @@
Hello :) Before you create an issue please read the following message:
My name is Roman and I'm the only developer of this app.
I will NOT contribute any more code to this repository ever again.
This repository is mostly for sharing the knowledge I gained during development.
At the moment I dedicate all my time to a startup and working on a new and very modern update to eqMac.
This new update will be completely rewritten from scratch and have many more new features and will be massively more stable (at least that't the plan).
I plan to release the new version in Q3 of 2018.
Thank you for your patience and giving eqMac a go :)
If you need help with eqMac please join our Slack Group:
https://join.slack.com/t/eqmac/shared_invite/enQtMjk4NDkwNzEzOTA4LTg4OWFlYWFjNGQzZTJiM2RmMDI4MTUzMjk5ZTk1ZTkwYzk5NTk1ZDMwNTc1ZmU2MDdmNzRhNjc4ZTBhOWM2MzA
That's your best bet at getting some help from me or the community.
GitHub is only for source-code related issues.
Still would like to report a bug or suggest a feature I can implement in the next version?
Please make sure you search through the Open and Closed Issues people have already submitted:
https://github.com/nodeful/eqMac2/issues?utf8=%E2%9C%93&q=is%3Aissue+
This eliviates the posibility of people creating duplicate issues.

8
.gitignore vendored
View File

@ -2,5 +2,9 @@ Pods/
.DS_Store
.DS_Store/
*/.DS_Store
eqMac2.xcworkspace/xcuserdata/
eqMac2.xcodeproj/xcuserdata
*.xcworkspace/xcuserdata
*.xcodeproj/xcuserdata
native/build
node_modules
.env
dist

View File

@ -1,46 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at bitgapp@bitgapp.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,31 +0,0 @@
## Contributing Guide
---
### Submitting Issues (Bug reports)
If you found a bug in eqMac2, please follow these steps to properly report it:
1. Sign-up / Log-in to GitHub
2. Go to [Issues tab](https://github.com/romankisil/eqMac2/issues) **and make sure your issue was not reported yet**
3. **If issue wasn't reported yet**, create a new one.
3. Set the Label (on the right) to Bug or any other appropriate
4. Describe the Bug as much as possible
5. If possible include some Screenshots
### Contributing your code
1. First, create an Issue with an 'enchancement' or 'bug' label
2. Before doing any work, wait for someone to approve or discuss the issue
3. Once work has been approved and/or coordinated, fork the repository
4. Write code in your Forked repository. Make sure to properly comment complex solutions
5. Once you are happy with your code, test it until no bugs are prevelant.
6. Submit a [New Pull Request](https://github.com/romankisil/eqMac2/pulls) and wait for someone to review it.
## How to build?
Please install [CocoaPods](https://cocoapods.org/) dependency manager on your Mac.
Then in Terminal:
```
git clone https://github.com/romankisil/eqMac2.git
cd eqMac2/
pod install
open eqMac2.xcworkspace
```
And then ⌘R

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 Roman Kisil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

16
Podfile
View File

@ -1,16 +0,0 @@
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'eqMac2' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
use_frameworks!
platform :osx, '10.10'
project 'eqMac2.xcodeproj'
# Pods for eqMac
pod 'STPrivilegedTask', '~> 1.0'
pod 'AFNetworking', '~> 3.1'
pod 'Sparkle'
end
workspace 'eqMac2'

View File

@ -1,30 +0,0 @@
PODS:
- AFNetworking (3.1.0):
- AFNetworking/NSURLSession (= 3.1.0)
- AFNetworking/Reachability (= 3.1.0)
- AFNetworking/Security (= 3.1.0)
- AFNetworking/Serialization (= 3.1.0)
- AFNetworking/UIKit (= 3.1.0)
- AFNetworking/NSURLSession (3.1.0):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (3.1.0)
- AFNetworking/Security (3.1.0)
- AFNetworking/Serialization (3.1.0)
- Sparkle (1.17.0)
- STPrivilegedTask (1.0.1)
DEPENDENCIES:
- AFNetworking (~> 3.1)
- Sparkle
- STPrivilegedTask (~> 1.0)
SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
Sparkle: ccfb47699feea7b40b51cf3176f69404e5b1da6c
STPrivilegedTask: 103f97827454e786074640cf89d303be344498c7
PODFILE CHECKSUM: a1653c2ce3795ff6ede78ef324f52c06bda13087
COCOAPODS: 1.3.1

View File

@ -1,61 +0,0 @@
<h1 align="center">
<a href="https://bitgapp.com/eqmac"><img src="https://github.com/romankisil/eqMac2/blob/master/eqMac2/Assets/Assets/Icons/256x256.png?raw=true?raw=true" alt="eqMac2 - System-Wide Equalizer for the Mac" width="200"></a>
<br>
eqMac2
</h1>
<h4 align="center">System-Wide Equalizer for the Mac</h4>
<p align="center">
<a href="https://join.slack.com/t/eqmac/shared_invite/enQtMjk4NDkwNzEzOTA4LTg4OWFlYWFjNGQzZTJiM2RmMDI4MTUzMjk5ZTk1ZTkwYzk5NTk1ZDMwNTc1ZmU2MDdmNzRhNjc4ZTBhOWM2MzA"><img src="https://img.shields.io/badge/slack-workspace-pink.svg" alt="chat on slack"></a>
<a href="http://twitter.com/eqMacApp"><img src="https://img.shields.io/twitter/follow/eqMacApp.svg?style=social" alt="Twitter"></a>
<a href="https://github.com/romankisil/eqMac2/releases"><img src="https://img.shields.io/github/downloads/romankisil/eqMac2/total.svg" alt="Download"></a>+ 127k (Legacy)
</p>
<br>
<p align="center">
<a href="https://bitgapp.com/eqmac"><img alt="eqMac2 Screenshot EQ" height="300" src="https://user-images.githubusercontent.com/8472525/33244041-488cf4b4-d2e8-11e7-986c-49826dd853e1.png"></a>
</p>
## Warning! Volume bug with wireless devices
Until this bug is fixed you may experience sudden loud changes in volume level!
https://github.com/nodeful/eqMac2/issues/112
## How to install?
Best way to install eqMac2 is from the website: https://bitgapp.com/eqmac
Or if you use [Homebrew](https://brew.sh/): `brew cask install eqmac`
## How it started?
If you are interested to know how eqMac was created, you can read the [Story](https://github.com/romankisil/eqMac2/blob/master/STORY.md)
## How to help?
If you are an Objective-C / C++ developer, please read the [Contribution Guide](https://github.com/romankisil/eqMac2/blob/master/CONTRIBUTING.md)
If you are a user, you can always help by [Reporting Bugs](https://github.com/romankisil/eqMac2/blob/master/CONTRIBUTING.md)
and/or [making direct contributions from the website](https://bitgapp.com/eqmac/#/donate)
## How to build?
Please install [CocoaPods](https://cocoapods.org/) dependency manager on your Mac.
Then in Terminal:
```
git clone https://github.com/nodeful/eqMac2.git
cd eqMac2/
pod install
open eqMac2.xcworkspace
```
And then ⌘R
## How it works
I basically took Apple's [CAPlayThrough example](https://developer.apple.com/library/content/samplecode/CAPlayThrough/Introduction/Intro.html) and modified the AUGraph to have an EQ node. Combined it with [SoundFlower Audio Driver](https://github.com/mattingalls/Soundflower) and it just worked.
<p align="center">
<img alt="eqMac2 Diagram" src="https://user-images.githubusercontent.com/8472525/29003031-13d1cd60-7aa7-11e7-9868-6afc36a34b52.jpg">
</p>

View File

@ -1,16 +0,0 @@
### The story so far:
#### Me:
Hey, my name is Roman and I'm mainly a Full Stack TypeScript developer, Objective-C is just a hobby.
#### Idea:
In 2015 I finished my University degree (Computer Hardware and Software Engineering course) and was pretty bored. Back then I liked to listen to Music 24/7, but I always had cheap headphones and the experice wasn't the best. I knew I can make my headphones better with a good Audio Equalizer. Made some research and found Boom2, like all of us did. But when I looked at the price I felt disgusted. Being that I'm a fresh Software Developer graduate I was very keen to apply myself somewhere. I decided that I will build my own Equalizer.
#### eqMac1 Summer 2015:
Back then Objective-C was always my language of choice.
I've spent around a month building the first version of eqMac. Had to do loads of reading but mostly it was pretty simple. Due to stupidity I coded the entire UI rather than using the Interface Builder. Honestly, the hardest part was doing the Website where people could download the app.
I released eqMac v1 for Free in August of 2015 and it started to slowly gather attention. In the first year I got around 50k downloads, just from the website.
That year I took time off working on eqMac as I had to kick start my career.
#### eqMac2 Sept. 2016:
In Septermber of 2016 I felt more stable with personal life and decided to do a Second release of eqMac2. This time I thought I would do a Freemium model with a 'free' basic app and some paid 'premium' functionality (like support for Bluetooth etc.) I followed this goal for about 9 months, spent around 1000 hours making eqMac2 more stable and prettier than its predecessor. I was 90% of the way there, before I realised that I don't want to turn eqMac into a business and a full-time job (just wasn't enjoying native development that much anymore). I decided to make eqMac an Open-Source project with hopes that we as a community can achieve much more than me, working on it alone. As of June 2017 eqMac has 125k Downloads.
#### Donations:
Money is used to pay for Server Hosting, SSL certificates, CDN, Apple Developer Membership (To sign the app and Kext) and any other maintenance costs.

View File

@ -1,899 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
30A77E801BFB091100503E6E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E7F1BFB091100503E6E /* CoreAudio.framework */; };
30A77E821BFB091700503E6E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E811BFB091700503E6E /* Cocoa.framework */; };
30A77E841BFB092200503E6E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E831BFB092200503E6E /* Security.framework */; };
30A77E861BFB092B00503E6E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E851BFB092B00503E6E /* QuartzCore.framework */; };
30A77E881BFB093A00503E6E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E871BFB093A00503E6E /* IOKit.framework */; };
30A77E8A1BFB094700503E6E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E891BFB094700503E6E /* AudioToolbox.framework */; };
30A77E8C1BFB094F00503E6E /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A77E8B1BFB094F00503E6E /* AudioUnit.framework */; };
C7E49B3F727A9657BBC43E9B /* Pods_eqMac2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB898D1CC464E56A965D8E4A /* Pods_eqMac2.framework */; };
E01871471FAFC70C0084ECAA /* Logger.m in Sources */ = {isa = PBXBuildFile; fileRef = E01871461FAFC70C0084ECAA /* Logger.m */; };
E036A54F1FBE4C1400A4FF07 /* eqMac2Driver.kext in Resources */ = {isa = PBXBuildFile; fileRef = E036A54C1FBE3DE900A4FF07 /* eqMac2Driver.kext */; };
E04186141FBCB33400F4F845 /* EQClickableImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = E04186131FBCB33400F4F845 /* EQClickableImageView.m */; };
E04DBF491FC383F30017DB23 /* EQViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E04DBF4B1FC383F30017DB23 /* EQViewController.xib */; };
E07BF4B51D6B4BA400589F0C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E07BF4B41D6B4BA400589F0C /* WebKit.framework */; };
E080F8DA1FCB07640071A222 /* open_security_settings.scpt in Resources */ = {isa = PBXBuildFile; fileRef = E080F8D91FCB07640071A222 /* open_security_settings.scpt */; };
E09DCA731FC0B1CC00046CDC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E09DCA721FC09A8F00046CDC /* Assets.xcassets */; };
E09DCA771FC0BBE200046CDC /* eqMac2Helper.app in Resources */ = {isa = PBXBuildFile; fileRef = E09DCA761FC0BBDF00046CDC /* eqMac2Helper.app */; };
E0B5F08F1F25EEE4005C5F46 /* exitDark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F07D1F25EEE4005C5F46 /* exitDark.png */; };
E0B5F0901F25EEE4005C5F46 /* exitLight.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F07E1F25EEE4005C5F46 /* exitLight.png */; };
E0B5F0911F25EEE4005C5F46 /* saveDark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F07F1F25EEE4005C5F46 /* saveDark.png */; };
E0B5F0921F25EEE4005C5F46 /* saveLight.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0801F25EEE4005C5F46 /* saveLight.png */; };
E0B5F0931F25EEE4005C5F46 /* speakerDark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0811F25EEE4005C5F46 /* speakerDark.png */; };
E0B5F0941F25EEE4005C5F46 /* speakerLight.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0821F25EEE4005C5F46 /* speakerLight.png */; };
E0B5F0951F25EEE4005C5F46 /* statusItemDark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0831F25EEE4005C5F46 /* statusItemDark.png */; };
E0B5F0961F25EEE4005C5F46 /* statusItemLight.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0841F25EEE4005C5F46 /* statusItemLight.png */; };
E0B5F0971F25EEE4005C5F46 /* deleteDark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0851F25EEE4005C5F46 /* deleteDark.png */; };
E0B5F0981F25EEE4005C5F46 /* deleteLight.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0861F25EEE4005C5F46 /* deleteLight.png */; };
E0B5F0991F25EEE4005C5F46 /* vol1Dark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0871F25EEE4005C5F46 /* vol1Dark.png */; };
E0B5F09A1F25EEE4005C5F46 /* vol1Light.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0881F25EEE4005C5F46 /* vol1Light.png */; };
E0B5F09B1F25EEE4005C5F46 /* vol2Dark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F0891F25EEE4005C5F46 /* vol2Dark.png */; };
E0B5F09C1F25EEE4005C5F46 /* vol2Light.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F08A1F25EEE4005C5F46 /* vol2Light.png */; };
E0B5F09D1F25EEE4005C5F46 /* vol3Dark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F08B1F25EEE4005C5F46 /* vol3Dark.png */; };
E0B5F09E1F25EEE4005C5F46 /* vol3Light.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F08C1F25EEE4005C5F46 /* vol3Light.png */; };
E0B5F09F1F25EEE4005C5F46 /* vol4Dark.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F08D1F25EEE4005C5F46 /* vol4Dark.png */; };
E0B5F0A01F25EEE4005C5F46 /* vol4Light.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B5F08E1F25EEE4005C5F46 /* vol4Light.png */; };
E0B7814D1EF704660076B3AB /* API.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B7812C1EF704660076B3AB /* API.m */; };
E0B7814E1EF704660076B3AB /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B7812F1EF704660076B3AB /* Constants.m */; };
E0B7814F1EF704660076B3AB /* Devices.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B781321EF704660076B3AB /* Devices.mm */; };
E0B781511EF704660076B3AB /* EQEngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B781371EF704660076B3AB /* EQEngine.mm */; };
E0B781521EF704660076B3AB /* EQHost.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B7813A1EF704660076B3AB /* EQHost.mm */; };
E0B781541EF704660076B3AB /* defaultPresets.plist in Resources */ = {isa = PBXBuildFile; fileRef = E0B7813F1EF704660076B3AB /* defaultPresets.plist */; };
E0B781561EF704660076B3AB /* install_driver.sh in Resources */ = {isa = PBXBuildFile; fileRef = E0B781431EF704660076B3AB /* install_driver.sh */; };
E0B781571EF704660076B3AB /* uninstall_driver.sh in Resources */ = {isa = PBXBuildFile; fileRef = E0B781441EF704660076B3AB /* uninstall_driver.sh */; };
E0B7815A1EF704660076B3AB /* Storage.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B781491EF704660076B3AB /* Storage.m */; };
E0B7815B1EF704660076B3AB /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B7814C1EF704660076B3AB /* Utilities.m */; };
E0B781831EF704A20076B3AB /* AudioDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E0B7815E1EF704A20076B3AB /* AudioDevice.cpp */; };
E0B781841EF704A20076B3AB /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E0B781611EF704A20076B3AB /* CARingBuffer.cpp */; };
E0B781851EF704A20076B3AB /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E0B7816A1EF704A20076B3AB /* CAStreamBasicDescription.cpp */; };
E0B781861EF704A20076B3AB /* EQViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B7816F1EF704A20076B3AB /* EQViewController.mm */; };
E0B781881EF704A20076B3AB /* SliderGraphView.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B781731EF704A20076B3AB /* SliderGraphView.m */; };
E0B7818B1EF704A20076B3AB /* eqMacStatusItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B7817B1EF704A20076B3AB /* eqMacStatusItemView.m */; };
E0B781AD1EF704BA0076B3AB /* blueLine.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781911EF704BA0076B3AB /* blueLine.png */; };
E0B781AF1EF704BA0076B3AB /* 1024x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781941EF704BA0076B3AB /* 1024x1024.png */; };
E0B781B01EF704BA0076B3AB /* 128x128.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781951EF704BA0076B3AB /* 128x128.png */; };
E0B781B11EF704BA0076B3AB /* 16x16.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781961EF704BA0076B3AB /* 16x16.png */; };
E0B781B21EF704BA0076B3AB /* 24x24.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781971EF704BA0076B3AB /* 24x24.png */; };
E0B781B31EF704BA0076B3AB /* 256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781981EF704BA0076B3AB /* 256x256.png */; };
E0B781B41EF704BA0076B3AB /* 32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B781991EF704BA0076B3AB /* 32x32.png */; };
E0B781B51EF704BA0076B3AB /* 48x48.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B7819A1EF704BA0076B3AB /* 48x48.png */; };
E0B781B61EF704BA0076B3AB /* 512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B7819B1EF704BA0076B3AB /* 512x512.png */; };
E0B781B71EF704BA0076B3AB /* 64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B7819C1EF704BA0076B3AB /* 64x64.png */; };
E0B781B81EF704BA0076B3AB /* 96x96.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B7819D1EF704BA0076B3AB /* 96x96.png */; };
E0B781B91EF704BA0076B3AB /* redLine.png in Resources */ = {isa = PBXBuildFile; fileRef = E0B7819E1EF704BA0076B3AB /* redLine.png */; };
E0B781CD1EF706670076B3AB /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B781C81EF706670076B3AB /* AppDelegate.mm */; };
E0B781CE1EF706670076B3AB /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E0B781C91EF706670076B3AB /* Info.plist */; };
E0B781CF1EF706670076B3AB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B781CA1EF706670076B3AB /* main.m */; };
E0B781D01EF706670076B3AB /* NSAppEventCather.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B781CC1EF706670076B3AB /* NSAppEventCather.m */; };
E0D7AA091FB98E80002952DE /* EQPromotionWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = E0D7AA071FB98E80002952DE /* EQPromotionWindowController.m */; };
E0D7AA0A1FB98E80002952DE /* EQPromotionWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E0D7AA081FB98E80002952DE /* EQPromotionWindowController.xib */; };
E0FC9EC71FC3822200BECC9E /* Main.xib in Resources */ = {isa = PBXBuildFile; fileRef = E0FC9EC61FC3821D00BECC9E /* Main.xib */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
E0101BDD1C995D9C008091E9 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
306DA1C71BEF965F002CB1C9 /* eqMac2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = eqMac2.app; sourceTree = BUILT_PRODUCTS_DIR; };
30A77E7F1BFB091100503E6E /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
30A77E811BFB091700503E6E /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
30A77E831BFB092200503E6E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
30A77E851BFB092B00503E6E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
30A77E871BFB093A00503E6E /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
30A77E891BFB094700503E6E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
30A77E8B1BFB094F00503E6E /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
614DEEEB6C06E6431C8B7EC2 /* Pods-eqMac2.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-eqMac2.release.xcconfig"; path = "Pods/Target Support Files/Pods-eqMac2/Pods-eqMac2.release.xcconfig"; sourceTree = "<group>"; };
A44CF14B89CD3E798D15238B /* Pods-eqMac2.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-eqMac2.debug.xcconfig"; path = "Pods/Target Support Files/Pods-eqMac2/Pods-eqMac2.debug.xcconfig"; sourceTree = "<group>"; };
A7CD694314F86C465E4A5F8B /* libPods-eqMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-eqMac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CB898D1CC464E56A965D8E4A /* Pods_eqMac2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_eqMac2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E01871451FAFC70C0084ECAA /* Logger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = "<group>"; };
E01871461FAFC70C0084ECAA /* Logger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Logger.m; sourceTree = "<group>"; };
E036A54C1FBE3DE900A4FF07 /* eqMac2Driver.kext */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.kernel-extension"; path = eqMac2Driver.kext; sourceTree = "<group>"; };
E04186121FBCB33400F4F845 /* EQClickableImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQClickableImageView.h; sourceTree = "<group>"; };
E04186131FBCB33400F4F845 /* EQClickableImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQClickableImageView.m; sourceTree = "<group>"; };
E04DBF4A1FC383F30017DB23 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/EQViewController.xib; sourceTree = "<group>"; };
E07BF4B41D6B4BA400589F0C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
E080F8D91FCB07640071A222 /* open_security_settings.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = open_security_settings.scpt; sourceTree = "<group>"; };
E09DCA721FC09A8F00046CDC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E09DCA761FC0BBDF00046CDC /* eqMac2Helper.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = eqMac2Helper.app; sourceTree = "<group>"; };
E0B0A7E51EA023F800D2BB98 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
E0B5F07D1F25EEE4005C5F46 /* exitDark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = exitDark.png; sourceTree = "<group>"; };
E0B5F07E1F25EEE4005C5F46 /* exitLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = exitLight.png; sourceTree = "<group>"; };
E0B5F07F1F25EEE4005C5F46 /* saveDark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = saveDark.png; sourceTree = "<group>"; };
E0B5F0801F25EEE4005C5F46 /* saveLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = saveLight.png; sourceTree = "<group>"; };
E0B5F0811F25EEE4005C5F46 /* speakerDark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speakerDark.png; sourceTree = "<group>"; };
E0B5F0821F25EEE4005C5F46 /* speakerLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speakerLight.png; sourceTree = "<group>"; };
E0B5F0831F25EEE4005C5F46 /* statusItemDark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusItemDark.png; sourceTree = "<group>"; };
E0B5F0841F25EEE4005C5F46 /* statusItemLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusItemLight.png; sourceTree = "<group>"; };
E0B5F0851F25EEE4005C5F46 /* deleteDark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = deleteDark.png; sourceTree = "<group>"; };
E0B5F0861F25EEE4005C5F46 /* deleteLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = deleteLight.png; sourceTree = "<group>"; };
E0B5F0871F25EEE4005C5F46 /* vol1Dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol1Dark.png; sourceTree = "<group>"; };
E0B5F0881F25EEE4005C5F46 /* vol1Light.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol1Light.png; sourceTree = "<group>"; };
E0B5F0891F25EEE4005C5F46 /* vol2Dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol2Dark.png; sourceTree = "<group>"; };
E0B5F08A1F25EEE4005C5F46 /* vol2Light.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol2Light.png; sourceTree = "<group>"; };
E0B5F08B1F25EEE4005C5F46 /* vol3Dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol3Dark.png; sourceTree = "<group>"; };
E0B5F08C1F25EEE4005C5F46 /* vol3Light.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol3Light.png; sourceTree = "<group>"; };
E0B5F08D1F25EEE4005C5F46 /* vol4Dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol4Dark.png; sourceTree = "<group>"; };
E0B5F08E1F25EEE4005C5F46 /* vol4Light.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vol4Light.png; sourceTree = "<group>"; };
E0B7812B1EF704660076B3AB /* API.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = API.h; sourceTree = "<group>"; };
E0B7812C1EF704660076B3AB /* API.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = API.m; sourceTree = "<group>"; };
E0B7812E1EF704660076B3AB /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
E0B7812F1EF704660076B3AB /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; };
E0B781311EF704660076B3AB /* Devices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Devices.h; sourceTree = "<group>"; };
E0B781321EF704660076B3AB /* Devices.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Devices.mm; sourceTree = "<group>"; };
E0B781361EF704660076B3AB /* EQEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EQEngine.h; sourceTree = "<group>"; };
E0B781371EF704660076B3AB /* EQEngine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EQEngine.mm; sourceTree = "<group>"; };
E0B781391EF704660076B3AB /* EQHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EQHost.h; sourceTree = "<group>"; };
E0B7813A1EF704660076B3AB /* EQHost.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EQHost.mm; sourceTree = "<group>"; };
E0B7813F1EF704660076B3AB /* defaultPresets.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = defaultPresets.plist; sourceTree = "<group>"; };
E0B781431EF704660076B3AB /* install_driver.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = install_driver.sh; sourceTree = "<group>"; };
E0B781441EF704660076B3AB /* uninstall_driver.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = uninstall_driver.sh; sourceTree = "<group>"; };
E0B781481EF704660076B3AB /* Storage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Storage.h; sourceTree = "<group>"; };
E0B781491EF704660076B3AB /* Storage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Storage.m; sourceTree = "<group>"; };
E0B7814B1EF704660076B3AB /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utilities.h; sourceTree = "<group>"; };
E0B7814C1EF704660076B3AB /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utilities.m; sourceTree = "<group>"; };
E0B7815E1EF704A20076B3AB /* AudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDevice.cpp; sourceTree = "<group>"; };
E0B7815F1EF704A20076B3AB /* AudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDevice.h; sourceTree = "<group>"; };
E0B781611EF704A20076B3AB /* CARingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CARingBuffer.cpp; sourceTree = "<group>"; };
E0B781621EF704A20076B3AB /* CARingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CARingBuffer.h; sourceTree = "<group>"; };
E0B781641EF704A20076B3AB /* CAAtomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAtomic.h; sourceTree = "<group>"; };
E0B781651EF704A20076B3AB /* CAAutoDisposer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAAutoDisposer.h; sourceTree = "<group>"; };
E0B781661EF704A20076B3AB /* CABitOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CABitOperations.h; sourceTree = "<group>"; };
E0B781671EF704A20076B3AB /* CADebugMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugMacros.h; sourceTree = "<group>"; };
E0B781681EF704A20076B3AB /* CADebugPrintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CADebugPrintf.h; sourceTree = "<group>"; };
E0B781691EF704A20076B3AB /* CAMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAMath.h; sourceTree = "<group>"; };
E0B7816A1EF704A20076B3AB /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = "<group>"; };
E0B7816B1EF704A20076B3AB /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = "<group>"; };
E0B7816E1EF704A20076B3AB /* EQViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EQViewController.h; sourceTree = "<group>"; };
E0B7816F1EF704A20076B3AB /* EQViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EQViewController.mm; sourceTree = "<group>"; };
E0B781721EF704A20076B3AB /* SliderGraphView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SliderGraphView.h; sourceTree = "<group>"; };
E0B781731EF704A20076B3AB /* SliderGraphView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SliderGraphView.m; sourceTree = "<group>"; };
E0B7817A1EF704A20076B3AB /* eqMacStatusItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eqMacStatusItemView.h; sourceTree = "<group>"; };
E0B7817B1EF704A20076B3AB /* eqMacStatusItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = eqMacStatusItemView.m; sourceTree = "<group>"; };
E0B781911EF704BA0076B3AB /* blueLine.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blueLine.png; sourceTree = "<group>"; };
E0B781941EF704BA0076B3AB /* 1024x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 1024x1024.png; sourceTree = "<group>"; };
E0B781951EF704BA0076B3AB /* 128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 128x128.png; sourceTree = "<group>"; };
E0B781961EF704BA0076B3AB /* 16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 16x16.png; sourceTree = "<group>"; };
E0B781971EF704BA0076B3AB /* 24x24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 24x24.png; sourceTree = "<group>"; };
E0B781981EF704BA0076B3AB /* 256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 256x256.png; sourceTree = "<group>"; };
E0B781991EF704BA0076B3AB /* 32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 32x32.png; sourceTree = "<group>"; };
E0B7819A1EF704BA0076B3AB /* 48x48.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 48x48.png; sourceTree = "<group>"; };
E0B7819B1EF704BA0076B3AB /* 512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 512x512.png; sourceTree = "<group>"; };
E0B7819C1EF704BA0076B3AB /* 64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 64x64.png; sourceTree = "<group>"; };
E0B7819D1EF704BA0076B3AB /* 96x96.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 96x96.png; sourceTree = "<group>"; };
E0B7819E1EF704BA0076B3AB /* redLine.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redLine.png; sourceTree = "<group>"; };
E0B781C71EF706670076B3AB /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
E0B781C81EF706670076B3AB /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = "<group>"; };
E0B781C91EF706670076B3AB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E0B781CA1EF706670076B3AB /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
E0B781CB1EF706670076B3AB /* NSAppEventCatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSAppEventCatcher.h; sourceTree = "<group>"; };
E0B781CC1EF706670076B3AB /* NSAppEventCather.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSAppEventCather.m; sourceTree = "<group>"; };
E0D7AA061FB98E80002952DE /* EQPromotionWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EQPromotionWindowController.h; sourceTree = "<group>"; };
E0D7AA071FB98E80002952DE /* EQPromotionWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EQPromotionWindowController.m; sourceTree = "<group>"; };
E0D7AA081FB98E80002952DE /* EQPromotionWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EQPromotionWindowController.xib; sourceTree = "<group>"; };
E0FC9EC61FC3821D00BECC9E /* Main.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Main.xib; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
306DA1C41BEF965F002CB1C9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E07BF4B51D6B4BA400589F0C /* WebKit.framework in Frameworks */,
30A77E8C1BFB094F00503E6E /* AudioUnit.framework in Frameworks */,
30A77E8A1BFB094700503E6E /* AudioToolbox.framework in Frameworks */,
30A77E881BFB093A00503E6E /* IOKit.framework in Frameworks */,
30A77E861BFB092B00503E6E /* QuartzCore.framework in Frameworks */,
30A77E841BFB092200503E6E /* Security.framework in Frameworks */,
30A77E821BFB091700503E6E /* Cocoa.framework in Frameworks */,
30A77E801BFB091100503E6E /* CoreAudio.framework in Frameworks */,
C7E49B3F727A9657BBC43E9B /* Pods_eqMac2.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
306DA1BE1BEF965F002CB1C9 = {
isa = PBXGroup;
children = (
306DA1C91BEF965F002CB1C9 /* eqMac2 */,
306DA1C81BEF965F002CB1C9 /* Products */,
30A77E8D1BFB097400503E6E /* Frameworks */,
6D3D49CE95FBA49AB1FBC4BF /* Pods */,
);
sourceTree = "<group>";
};
306DA1C81BEF965F002CB1C9 /* Products */ = {
isa = PBXGroup;
children = (
306DA1C71BEF965F002CB1C9 /* eqMac2.app */,
);
name = Products;
sourceTree = "<group>";
};
306DA1C91BEF965F002CB1C9 /* eqMac2 */ = {
isa = PBXGroup;
children = (
E0B781291EF704660076B3AB /* Source */,
E0B7815C1EF704A20076B3AB /* Libs */,
E0616A591FADCC7000B5B19E /* Supporting files */,
E0B7818F1EF704BA0076B3AB /* Assets */,
);
path = eqMac2;
sourceTree = "<group>";
};
30A77E8D1BFB097400503E6E /* Frameworks */ = {
isa = PBXGroup;
children = (
E0B0A7E51EA023F800D2BB98 /* Carbon.framework */,
E07BF4B41D6B4BA400589F0C /* WebKit.framework */,
30A77E8B1BFB094F00503E6E /* AudioUnit.framework */,
30A77E891BFB094700503E6E /* AudioToolbox.framework */,
30A77E871BFB093A00503E6E /* IOKit.framework */,
30A77E851BFB092B00503E6E /* QuartzCore.framework */,
30A77E831BFB092200503E6E /* Security.framework */,
30A77E811BFB091700503E6E /* Cocoa.framework */,
30A77E7F1BFB091100503E6E /* CoreAudio.framework */,
A7CD694314F86C465E4A5F8B /* libPods-eqMac.a */,
CB898D1CC464E56A965D8E4A /* Pods_eqMac2.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
6D3D49CE95FBA49AB1FBC4BF /* Pods */ = {
isa = PBXGroup;
children = (
A44CF14B89CD3E798D15238B /* Pods-eqMac2.debug.xcconfig */,
614DEEEB6C06E6431C8B7EC2 /* Pods-eqMac2.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
E01871441FAFC6E10084ECAA /* Logger */ = {
isa = PBXGroup;
children = (
E01871451FAFC70C0084ECAA /* Logger.h */,
E01871461FAFC70C0084ECAA /* Logger.m */,
);
path = Logger;
sourceTree = "<group>";
};
E04186111FBCB30700F4F845 /* EQClickableImageView */ = {
isa = PBXGroup;
children = (
E04186121FBCB33400F4F845 /* EQClickableImageView.h */,
E04186131FBCB33400F4F845 /* EQClickableImageView.m */,
);
path = EQClickableImageView;
sourceTree = "<group>";
};
E0616A591FADCC7000B5B19E /* Supporting files */ = {
isa = PBXGroup;
children = (
E09DCA761FC0BBDF00046CDC /* eqMac2Helper.app */,
E036A54C1FBE3DE900A4FF07 /* eqMac2Driver.kext */,
E0B7813F1EF704660076B3AB /* defaultPresets.plist */,
E0B781CA1EF706670076B3AB /* main.m */,
E0FC9EC61FC3821D00BECC9E /* Main.xib */,
E0B781C91EF706670076B3AB /* Info.plist */,
);
path = "Supporting files";
sourceTree = "<group>";
};
E0B781291EF704660076B3AB /* Source */ = {
isa = PBXGroup;
children = (
E0B781C71EF706670076B3AB /* AppDelegate.h */,
E0B781C81EF706670076B3AB /* AppDelegate.mm */,
E0B781CB1EF706670076B3AB /* NSAppEventCatcher.h */,
E0B781CC1EF706670076B3AB /* NSAppEventCather.m */,
E0B7812A1EF704660076B3AB /* API */,
E0B7812D1EF704660076B3AB /* Constants */,
E0B781301EF704660076B3AB /* Devices */,
E04186111FBCB30700F4F845 /* EQClickableImageView */,
E0B7816D1EF704A20076B3AB /* EQViewController */,
E0D7AA051FB98E58002952DE /* EQPromotionWindowController */,
E0B781791EF704A20076B3AB /* EQStatusItemView */,
E01871441FAFC6E10084ECAA /* Logger */,
E0B781711EF704A20076B3AB /* SliderGraphView */,
E0B781351EF704660076B3AB /* EQEngine */,
E0B781381EF704660076B3AB /* EQHost */,
E0B781421EF704660076B3AB /* Scripts */,
E0B781471EF704660076B3AB /* Storage */,
E0B7814A1EF704660076B3AB /* Utilities */,
);
path = Source;
sourceTree = "<group>";
};
E0B7812A1EF704660076B3AB /* API */ = {
isa = PBXGroup;
children = (
E0B7812B1EF704660076B3AB /* API.h */,
E0B7812C1EF704660076B3AB /* API.m */,
);
path = API;
sourceTree = "<group>";
};
E0B7812D1EF704660076B3AB /* Constants */ = {
isa = PBXGroup;
children = (
E0B7812E1EF704660076B3AB /* Constants.h */,
E0B7812F1EF704660076B3AB /* Constants.m */,
);
path = Constants;
sourceTree = "<group>";
};
E0B781301EF704660076B3AB /* Devices */ = {
isa = PBXGroup;
children = (
E0B781311EF704660076B3AB /* Devices.h */,
E0B781321EF704660076B3AB /* Devices.mm */,
);
path = Devices;
sourceTree = "<group>";
};
E0B781351EF704660076B3AB /* EQEngine */ = {
isa = PBXGroup;
children = (
E0B781361EF704660076B3AB /* EQEngine.h */,
E0B781371EF704660076B3AB /* EQEngine.mm */,
);
path = EQEngine;
sourceTree = "<group>";
};
E0B781381EF704660076B3AB /* EQHost */ = {
isa = PBXGroup;
children = (
E0B781391EF704660076B3AB /* EQHost.h */,
E0B7813A1EF704660076B3AB /* EQHost.mm */,
);
path = EQHost;
sourceTree = "<group>";
};
E0B781421EF704660076B3AB /* Scripts */ = {
isa = PBXGroup;
children = (
E080F8D91FCB07640071A222 /* open_security_settings.scpt */,
E0B781431EF704660076B3AB /* install_driver.sh */,
E0B781441EF704660076B3AB /* uninstall_driver.sh */,
);
path = Scripts;
sourceTree = "<group>";
};
E0B781471EF704660076B3AB /* Storage */ = {
isa = PBXGroup;
children = (
E0B781481EF704660076B3AB /* Storage.h */,
E0B781491EF704660076B3AB /* Storage.m */,
);
path = Storage;
sourceTree = "<group>";
};
E0B7814A1EF704660076B3AB /* Utilities */ = {
isa = PBXGroup;
children = (
E0B7814B1EF704660076B3AB /* Utilities.h */,
E0B7814C1EF704660076B3AB /* Utilities.m */,
);
path = Utilities;
sourceTree = "<group>";
};
E0B7815C1EF704A20076B3AB /* Libs */ = {
isa = PBXGroup;
children = (
E0B7815D1EF704A20076B3AB /* AudioDevice */,
E0B781601EF704A20076B3AB /* CARingBuffer */,
E0B781631EF704A20076B3AB /* Misc */,
);
path = Libs;
sourceTree = "<group>";
};
E0B7815D1EF704A20076B3AB /* AudioDevice */ = {
isa = PBXGroup;
children = (
E0B7815E1EF704A20076B3AB /* AudioDevice.cpp */,
E0B7815F1EF704A20076B3AB /* AudioDevice.h */,
);
path = AudioDevice;
sourceTree = "<group>";
};
E0B781601EF704A20076B3AB /* CARingBuffer */ = {
isa = PBXGroup;
children = (
E0B781611EF704A20076B3AB /* CARingBuffer.cpp */,
E0B781621EF704A20076B3AB /* CARingBuffer.h */,
);
path = CARingBuffer;
sourceTree = "<group>";
};
E0B781631EF704A20076B3AB /* Misc */ = {
isa = PBXGroup;
children = (
E0B781641EF704A20076B3AB /* CAAtomic.h */,
E0B781651EF704A20076B3AB /* CAAutoDisposer.h */,
E0B781661EF704A20076B3AB /* CABitOperations.h */,
E0B781671EF704A20076B3AB /* CADebugMacros.h */,
E0B781681EF704A20076B3AB /* CADebugPrintf.h */,
E0B781691EF704A20076B3AB /* CAMath.h */,
E0B7816A1EF704A20076B3AB /* CAStreamBasicDescription.cpp */,
E0B7816B1EF704A20076B3AB /* CAStreamBasicDescription.h */,
);
path = Misc;
sourceTree = "<group>";
};
E0B7816D1EF704A20076B3AB /* EQViewController */ = {
isa = PBXGroup;
children = (
E0B7816E1EF704A20076B3AB /* EQViewController.h */,
E0B7816F1EF704A20076B3AB /* EQViewController.mm */,
E04DBF4B1FC383F30017DB23 /* EQViewController.xib */,
);
path = EQViewController;
sourceTree = "<group>";
};
E0B781711EF704A20076B3AB /* SliderGraphView */ = {
isa = PBXGroup;
children = (
E0B781721EF704A20076B3AB /* SliderGraphView.h */,
E0B781731EF704A20076B3AB /* SliderGraphView.m */,
);
path = SliderGraphView;
sourceTree = "<group>";
};
E0B781791EF704A20076B3AB /* EQStatusItemView */ = {
isa = PBXGroup;
children = (
E0B7817A1EF704A20076B3AB /* eqMacStatusItemView.h */,
E0B7817B1EF704A20076B3AB /* eqMacStatusItemView.m */,
);
path = EQStatusItemView;
sourceTree = "<group>";
};
E0B7818F1EF704BA0076B3AB /* Assets */ = {
isa = PBXGroup;
children = (
E09DCA721FC09A8F00046CDC /* Assets.xcassets */,
E0B781901EF704BA0076B3AB /* Assets */,
);
path = Assets;
sourceTree = "<group>";
};
E0B781901EF704BA0076B3AB /* Assets */ = {
isa = PBXGroup;
children = (
E0B5F07D1F25EEE4005C5F46 /* exitDark.png */,
E0B5F07E1F25EEE4005C5F46 /* exitLight.png */,
E0B5F07F1F25EEE4005C5F46 /* saveDark.png */,
E0B5F0801F25EEE4005C5F46 /* saveLight.png */,
E0B5F0811F25EEE4005C5F46 /* speakerDark.png */,
E0B5F0821F25EEE4005C5F46 /* speakerLight.png */,
E0B5F0831F25EEE4005C5F46 /* statusItemDark.png */,
E0B5F0841F25EEE4005C5F46 /* statusItemLight.png */,
E0B5F0851F25EEE4005C5F46 /* deleteDark.png */,
E0B5F0861F25EEE4005C5F46 /* deleteLight.png */,
E0B5F0871F25EEE4005C5F46 /* vol1Dark.png */,
E0B5F0881F25EEE4005C5F46 /* vol1Light.png */,
E0B5F0891F25EEE4005C5F46 /* vol2Dark.png */,
E0B5F08A1F25EEE4005C5F46 /* vol2Light.png */,
E0B5F08B1F25EEE4005C5F46 /* vol3Dark.png */,
E0B5F08C1F25EEE4005C5F46 /* vol3Light.png */,
E0B5F08D1F25EEE4005C5F46 /* vol4Dark.png */,
E0B5F08E1F25EEE4005C5F46 /* vol4Light.png */,
E0B781911EF704BA0076B3AB /* blueLine.png */,
E0B781931EF704BA0076B3AB /* Icons */,
E0B7819E1EF704BA0076B3AB /* redLine.png */,
);
path = Assets;
sourceTree = "<group>";
};
E0B781931EF704BA0076B3AB /* Icons */ = {
isa = PBXGroup;
children = (
E0B781941EF704BA0076B3AB /* 1024x1024.png */,
E0B781951EF704BA0076B3AB /* 128x128.png */,
E0B781961EF704BA0076B3AB /* 16x16.png */,
E0B781971EF704BA0076B3AB /* 24x24.png */,
E0B781981EF704BA0076B3AB /* 256x256.png */,
E0B781991EF704BA0076B3AB /* 32x32.png */,
E0B7819A1EF704BA0076B3AB /* 48x48.png */,
E0B7819B1EF704BA0076B3AB /* 512x512.png */,
E0B7819C1EF704BA0076B3AB /* 64x64.png */,
E0B7819D1EF704BA0076B3AB /* 96x96.png */,
);
path = Icons;
sourceTree = "<group>";
};
E0D7AA051FB98E58002952DE /* EQPromotionWindowController */ = {
isa = PBXGroup;
children = (
E0D7AA061FB98E80002952DE /* EQPromotionWindowController.h */,
E0D7AA071FB98E80002952DE /* EQPromotionWindowController.m */,
E0D7AA081FB98E80002952DE /* EQPromotionWindowController.xib */,
);
path = EQPromotionWindowController;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
306DA1C61BEF965F002CB1C9 /* eqMac2 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 306DA1D81BEF965F002CB1C9 /* Build configuration list for PBXNativeTarget "eqMac2" */;
buildPhases = (
9E1691950E7383BA8C511F30 /* [CP] Check Pods Manifest.lock */,
306DA1C31BEF965F002CB1C9 /* Sources */,
306DA1C41BEF965F002CB1C9 /* Frameworks */,
306DA1C51BEF965F002CB1C9 /* Resources */,
E0101BDD1C995D9C008091E9 /* CopyFiles */,
069EEAEDF585E353EE09BB23 /* [CP] Embed Pods Frameworks */,
843AE5CDFC657801F95DC474 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = eqMac2;
productName = eqMacPro;
productReference = 306DA1C71BEF965F002CB1C9 /* eqMac2.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
306DA1BF1BEF965F002CB1C9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = bitgapp;
TargetAttributes = {
306DA1C61BEF965F002CB1C9 = {
CreatedOnToolsVersion = 7.0.1;
DevelopmentTeam = JZA6C97KJA;
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 306DA1C21BEF965F002CB1C9 /* Build configuration list for PBXProject "eqMac2" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 306DA1BE1BEF965F002CB1C9;
productRefGroup = 306DA1C81BEF965F002CB1C9 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
306DA1C61BEF965F002CB1C9 /* eqMac2 */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
306DA1C51BEF965F002CB1C9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E0B781B51EF704BA0076B3AB /* 48x48.png in Resources */,
E0B5F09D1F25EEE4005C5F46 /* vol3Dark.png in Resources */,
E04DBF491FC383F30017DB23 /* EQViewController.xib in Resources */,
E0FC9EC71FC3822200BECC9E /* Main.xib in Resources */,
E0B5F0A01F25EEE4005C5F46 /* vol4Light.png in Resources */,
E0B781B11EF704BA0076B3AB /* 16x16.png in Resources */,
E0B781B71EF704BA0076B3AB /* 64x64.png in Resources */,
E0D7AA0A1FB98E80002952DE /* EQPromotionWindowController.xib in Resources */,
E0B781B31EF704BA0076B3AB /* 256x256.png in Resources */,
E0B5F09A1F25EEE4005C5F46 /* vol1Light.png in Resources */,
E080F8DA1FCB07640071A222 /* open_security_settings.scpt in Resources */,
E09DCA771FC0BBE200046CDC /* eqMac2Helper.app in Resources */,
E0B5F0951F25EEE4005C5F46 /* statusItemDark.png in Resources */,
E0B5F08F1F25EEE4005C5F46 /* exitDark.png in Resources */,
E0B5F0991F25EEE4005C5F46 /* vol1Dark.png in Resources */,
E0B5F09C1F25EEE4005C5F46 /* vol2Light.png in Resources */,
E0B781B21EF704BA0076B3AB /* 24x24.png in Resources */,
E0B5F09F1F25EEE4005C5F46 /* vol4Dark.png in Resources */,
E0B5F0901F25EEE4005C5F46 /* exitLight.png in Resources */,
E0B781B81EF704BA0076B3AB /* 96x96.png in Resources */,
E0B781B61EF704BA0076B3AB /* 512x512.png in Resources */,
E0B5F09B1F25EEE4005C5F46 /* vol2Dark.png in Resources */,
E0B781CE1EF706670076B3AB /* Info.plist in Resources */,
E0B5F0961F25EEE4005C5F46 /* statusItemLight.png in Resources */,
E0B5F0971F25EEE4005C5F46 /* deleteDark.png in Resources */,
E09DCA731FC0B1CC00046CDC /* Assets.xcassets in Resources */,
E0B781541EF704660076B3AB /* defaultPresets.plist in Resources */,
E0B781AD1EF704BA0076B3AB /* blueLine.png in Resources */,
E0B781561EF704660076B3AB /* install_driver.sh in Resources */,
E0B781B91EF704BA0076B3AB /* redLine.png in Resources */,
E0B5F09E1F25EEE4005C5F46 /* vol3Light.png in Resources */,
E0B5F0941F25EEE4005C5F46 /* speakerLight.png in Resources */,
E0B5F0911F25EEE4005C5F46 /* saveDark.png in Resources */,
E0B5F0931F25EEE4005C5F46 /* speakerDark.png in Resources */,
E036A54F1FBE4C1400A4FF07 /* eqMac2Driver.kext in Resources */,
E0B781571EF704660076B3AB /* uninstall_driver.sh in Resources */,
E0B781B01EF704BA0076B3AB /* 128x128.png in Resources */,
E0B781AF1EF704BA0076B3AB /* 1024x1024.png in Resources */,
E0B5F0981F25EEE4005C5F46 /* deleteLight.png in Resources */,
E0B781B41EF704BA0076B3AB /* 32x32.png in Resources */,
E0B5F0921F25EEE4005C5F46 /* saveLight.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
069EEAEDF585E353EE09BB23 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-eqMac2/Pods-eqMac2-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
"${BUILT_PRODUCTS_DIR}/STPrivilegedTask/STPrivilegedTask.framework",
"${PODS_ROOT}/Sparkle/Sparkle.framework",
"${PODS_ROOT}/Sparkle/Sparkle.framework.dSYM",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/STPrivilegedTask.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework",
"${DWARF_DSYM_FOLDER_PATH}/Sparkle.framework.dSYM",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-eqMac2/Pods-eqMac2-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
843AE5CDFC657801F95DC474 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-eqMac2/Pods-eqMac2-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9E1691950E7383BA8C511F30 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-eqMac2-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
306DA1C31BEF965F002CB1C9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E0D7AA091FB98E80002952DE /* EQPromotionWindowController.m in Sources */,
E0B781861EF704A20076B3AB /* EQViewController.mm in Sources */,
E0B7818B1EF704A20076B3AB /* eqMacStatusItemView.m in Sources */,
E0B781841EF704A20076B3AB /* CARingBuffer.cpp in Sources */,
E0B781881EF704A20076B3AB /* SliderGraphView.m in Sources */,
E0B7814E1EF704660076B3AB /* Constants.m in Sources */,
E0B7814F1EF704660076B3AB /* Devices.mm in Sources */,
E0B781521EF704660076B3AB /* EQHost.mm in Sources */,
E0B781CF1EF706670076B3AB /* main.m in Sources */,
E0B7815B1EF704660076B3AB /* Utilities.m in Sources */,
E0B7814D1EF704660076B3AB /* API.m in Sources */,
E0B781D01EF706670076B3AB /* NSAppEventCather.m in Sources */,
E0B781831EF704A20076B3AB /* AudioDevice.cpp in Sources */,
E0B781CD1EF706670076B3AB /* AppDelegate.mm in Sources */,
E0B7815A1EF704660076B3AB /* Storage.m in Sources */,
E0B781511EF704660076B3AB /* EQEngine.mm in Sources */,
E04186141FBCB33400F4F845 /* EQClickableImageView.m in Sources */,
E0B781851EF704A20076B3AB /* CAStreamBasicDescription.cpp in Sources */,
E01871471FAFC70C0084ECAA /* Logger.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
E04DBF4B1FC383F30017DB23 /* EQViewController.xib */ = {
isa = PBXVariantGroup;
children = (
E04DBF4A1FC383F30017DB23 /* Base */,
);
name = EQViewController.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
306DA1D61BEF965F002CB1C9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = 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_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
306DA1D71BEF965F002CB1C9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = 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_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
306DA1D91BEF965F002CB1C9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A44CF14B89CD3E798D15238B /* Pods-eqMac2.debug.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Developer ID Application";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = JZA6C97KJA;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
"$(PROJECT_DIR)/eqMac",
);
GCC_INPUT_FILETYPE = automatic;
INFOPLIST_FILE = "$(SRCROOT)/eqMac2/Supporting files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqMac2;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "436b674f-56fa-48cd-9846-cd9ef65d7a8e";
PROVISIONING_PROFILE_SPECIFIER = "eqMac2 Distribution";
};
name = Debug;
};
306DA1DA1BEF965F002CB1C9 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 614DEEEB6C06E6431C8B7EC2 /* Pods-eqMac2.release.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Developer ID Application";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = JZA6C97KJA;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
"$(PROJECT_DIR)/eqMac",
);
GCC_INPUT_FILETYPE = automatic;
INFOPLIST_FILE = "$(SRCROOT)/eqMac2/Supporting files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqMac2;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
306DA1C21BEF965F002CB1C9 /* Build configuration list for PBXProject "eqMac2" */ = {
isa = XCConfigurationList;
buildConfigurations = (
306DA1D61BEF965F002CB1C9 /* Debug */,
306DA1D71BEF965F002CB1C9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
306DA1D81BEF965F002CB1C9 /* Build configuration list for PBXNativeTarget "eqMac2" */ = {
isa = XCConfigurationList;
buildConfigurations = (
306DA1D91BEF965F002CB1C9 /* Debug */,
306DA1DA1BEF965F002CB1C9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 306DA1BF1BEF965F002CB1C9 /* Project object */;
}

View File

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "eqMacPro/testAudioEngine.mm"
timestampString = "479310458.055517"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "126"
endingLineNumber = "126"
landmarkName = "initializeGraph()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "eqMacPro/RemoteDataService.m"
timestampString = "502988468.416514"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "43"
endingLineNumber = "43"
landmarkName = "-pingServer"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "eqMacPro/SliderGraphView.m"
timestampString = "501203732.935593"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "109"
endingLineNumber = "109"
landmarkName = "-drawRect:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "eqMacPro/AppDelegate.mm"
timestampString = "503158593.238314"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "60"
endingLineNumber = "60"
landmarkName = "-setupStatusBar"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>eqMac2.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict/>
</dict>
</plist>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:eqMac2.xcodeproj">
</FileRef>
<FileRef
location = "group:eqMac2Driver.xcodeproj">
</FileRef>
<FileRef
location = "group:eqMac2Helper.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,156 +0,0 @@
/*
File: AudioDevice.cpp
Abstract: CAPlayThough Classes.
Version: 1.2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2013 Apple Inc. All Rights Reserved.
*/
#include "AudioDevice.h"
void AudioDevice::Init(AudioDeviceID devid, bool isInput)
{
mID = devid;
mIsInput = isInput;
if (mID == kAudioDeviceUnknown) return;
UInt32 propsize = sizeof(Float32);
AudioObjectPropertyScope theScope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertySafetyOffset,
theScope,
0 }; // channel
AudioObjectGetPropertyData(mID,
&theAddress,
0,
NULL,
&propsize,
&mSafetyOffset);
propsize = sizeof(UInt32);
theAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
(AudioObjectGetPropertyData(mID,
&theAddress,
0,
NULL,
&propsize,
&mBufferSizeFrames));
propsize = sizeof(AudioStreamBasicDescription);
theAddress.mSelector = kAudioDevicePropertyStreamFormat;
(AudioObjectGetPropertyData(mID,
&theAddress,
0,
NULL,
&propsize,
&mFormat));
}
void AudioDevice::SetBufferSize(UInt32 size)
{
UInt32 propsize = sizeof(UInt32);
AudioObjectPropertyScope theScope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyBufferFrameSize,
theScope,
0 }; // channel
(AudioObjectSetPropertyData(mID, &theAddress, 0, NULL, propsize, &size));
(AudioObjectGetPropertyData(mID, &theAddress, 0, NULL, &propsize, &mBufferSizeFrames));
}
int AudioDevice::CountChannels()
{
OSStatus err;
UInt32 propSize;
int result = 0;
AudioObjectPropertyScope theScope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyStreamConfiguration,
theScope,
0 }; // channel
err = AudioObjectGetPropertyDataSize(mID, &theAddress, 0, NULL, &propSize);
if (err) return 0;
AudioBufferList *buflist = (AudioBufferList *)malloc(propSize);
err = AudioObjectGetPropertyData(mID, &theAddress, 0, NULL, &propSize, buflist);
if (!err) {
for (UInt32 i = 0; i < buflist->mNumberBuffers; ++i) {
result += buflist->mBuffers[i].mNumberChannels;
}
}
free(buflist);
return result;
}
OSStatus AudioDevice::SetSampleRate(Float64 sr) {
OSStatus err = noErr;
mFormat.mSampleRate = sr;
UInt32 size = sizeof(mFormat);
AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreamFormat, (mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput), 0 };
err = AudioObjectSetPropertyData(mID, &addr, 0, NULL, size, &mFormat);
if(mFormat.mSampleRate != sr) printf("Error in AudioDevice::SetSampleRate - sample rate mismatch!");
return err;
}
char * AudioDevice::GetName(char *buf, UInt32 maxlen)
{
AudioObjectPropertyScope theScope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyDeviceName,
theScope,
0 }; // channel
(AudioObjectGetPropertyData(mID, &theAddress, 0, NULL, &maxlen, buf));
return buf;
}

View File

@ -1,795 +0,0 @@
/*
File: CAStreamBasicDescription.cpp
Abstract: CAStreamBasicDescription.h
Version: 1.2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2013 Apple Inc. All Rights Reserved.
*/
#include "CAStreamBasicDescription.h"
#include "CAMath.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreFoundation/CFByteOrder.h>
#else
#include <CFByteOrder.h>
#endif
#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it
char *CAStringForOSType (OSType t, char *writeLocation)
{
char *p = writeLocation;
unsigned char str[4] = {0}, *q = str;
*(UInt32 *)str = CFSwapInt32HostToBig(t);
bool hasNonPrint = false;
for (int i = 0; i < 4; ++i) {
if (!(isprint(*q) && *q != '\\')) {
hasNonPrint = true;
break;
}
q++;
}
q = str;
if (hasNonPrint)
p += sprintf (p, "0x");
else
*p++ = '\'';
for (int i = 0; i < 4; ++i) {
if (hasNonPrint) {
p += sprintf(p, "%02X", *q++);
} else {
*p++ = *q++;
}
}
if (!hasNonPrint)
*p++ = '\'';
*p = '\0';
return writeLocation;
}
const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
CAStreamBasicDescription::CAStreamBasicDescription()
{
memset (this, 0, sizeof(AudioStreamBasicDescription));
}
CAStreamBasicDescription::CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
{
SetFrom(desc);
}
CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID,
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
UInt32 inBitsPerChannel, UInt32 inFormatFlags)
{
mSampleRate = inSampleRate;
mFormatID = inFormatID;
mBytesPerPacket = inBytesPerPacket;
mFramesPerPacket = inFramesPerPacket;
mBytesPerFrame = inBytesPerFrame;
mChannelsPerFrame = inChannelsPerFrame;
mBitsPerChannel = inBitsPerChannel;
mFormatFlags = inFormatFlags;
mReserved = 0;
}
char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize) const
{
int bufsize = (int)_bufsize; // must be signed to protect against overflow
char *theBuffer = buf;
int nc;
char formatID[24];
CAStringForOSType (mFormatID, formatID);
nc = snprintf(buf, bufsize, "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
buf += nc; if ((bufsize -= nc) <= 0) goto exit;
if (mFormatID == kAudioFormatLinearPCM) {
bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
int wordSize = SampleWordSize();
const char *endian = (wordSize > 1) ?
((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
const char *sign = isInt ?
((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
const char *floatInt = isInt ? "integer" : "float";
char packed[32];
if (wordSize > 0 && PackednessIsSignificant()) {
if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize);
else
snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize);
} else
packed[0] = '\0';
const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
char bitdepth[20];
int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
if (fracbits > 0)
snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
else
snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel);
/* nc =*/ snprintf(buf, bufsize, "%s-bit%s%s %s%s%s%s%s",
bitdepth, endian, sign, floatInt,
commaSpace, packed, align, deinter);
// buf += nc; if ((bufsize -= nc) <= 0) goto exit;
} else if (mFormatID == 'alac') { // kAudioFormatAppleLossless
int sourceBits = 0;
switch (mFormatFlags)
{
case 1: // kAppleLosslessFormatFlag_16BitSourceData
sourceBits = 16;
break;
case 2: // kAppleLosslessFormatFlag_20BitSourceData
sourceBits = 20;
break;
case 3: // kAppleLosslessFormatFlag_24BitSourceData
sourceBits = 24;
break;
case 4: // kAppleLosslessFormatFlag_32BitSourceData
sourceBits = 32;
break;
}
if (sourceBits)
nc = snprintf(buf, bufsize, "from %d-bit source, ", sourceBits);
else
nc = snprintf(buf, bufsize, "from UNKNOWN source bit depth, ");
buf += nc; if ((bufsize -= nc) <= 0) goto exit;
/* nc =*/ snprintf(buf, bufsize, "%d frames/packet", (int)mFramesPerPacket);
// buf += nc; if ((bufsize -= nc) <= 0) goto exit;
}
else
/* nc =*/ snprintf(buf, bufsize, "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame",
(int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame);
exit:
return theBuffer;
}
void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
{
// the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
{
// the canonical linear PCM format
ioDescription.mFormatFlags = kAudioFormatFlagsCanonical;
ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
ioDescription.mFramesPerPacket = 1;
ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
}
}
void CAStreamBasicDescription::NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription)
{
// the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
{
// the canonical linear PCM format
ioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
if(inNativeEndian)
{
#if TARGET_RT_BIG_ENDIAN
ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
#endif
}
else
{
#if TARGET_RT_LITTLE_ENDIAN
ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
#endif
}
ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
ioDescription.mFramesPerPacket = 1;
ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
}
}
void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
{
ioDescription.mSampleRate = 0;
ioDescription.mFormatID = 0;
ioDescription.mBytesPerPacket = 0;
ioDescription.mFramesPerPacket = 0;
ioDescription.mBytesPerFrame = 0;
ioDescription.mChannelsPerFrame = 0;
ioDescription.mBitsPerChannel = 0;
ioDescription.mFormatFlags = 0;
}
void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
{
if(fiszero(ioDescription.mSampleRate))
{
ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
}
if(ioDescription.mFormatID == 0)
{
ioDescription.mFormatID = inTemplateDescription.mFormatID;
}
if(ioDescription.mFormatFlags == 0)
{
ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
}
if(ioDescription.mBytesPerPacket == 0)
{
ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
}
if(ioDescription.mFramesPerPacket == 0)
{
ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
}
if(ioDescription.mBytesPerFrame == 0)
{
ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
}
if(ioDescription.mChannelsPerFrame == 0)
{
ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
}
if(ioDescription.mBitsPerChannel == 0)
{
ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
}
}
void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate)
{
if(inIncludeSampleRate)
{
int theCharactersWritten = snprintf(outName, inMaxNameLength, "%.0f ", inDescription.mSampleRate);
outName += theCharactersWritten;
inMaxNameLength -= theCharactersWritten;
}
switch(inDescription.mFormatID)
{
case kAudioFormatLinearPCM:
{
const char* theEndianString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
{
#if TARGET_RT_LITTLE_ENDIAN
theEndianString = "Big Endian";
#endif
}
else
{
#if TARGET_RT_BIG_ENDIAN
theEndianString = "Little Endian";
#endif
}
const char* theKindString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
{
theKindString = (inAbbreviate ? "Float" : "Floating Point");
}
else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
{
theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
}
else
{
theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
}
const char* thePackingString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
{
if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
{
thePackingString = "High";
}
else
{
thePackingString = "Low";
}
}
const char* theMixabilityString = NULL;
if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
{
theMixabilityString = "Mixable";
}
else
{
theMixabilityString = "Unmixable";
}
if(inAbbreviate)
{
if(theEndianString != NULL)
{
if(thePackingString != NULL)
{
snprintf(outName, inMaxNameLength, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
}
}
else
{
if(thePackingString != NULL)
{
snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
}
else
{
snprintf(outName, inMaxNameLength, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
}
}
}
else
{
if(theEndianString != NULL)
{
if(thePackingString != NULL)
{
snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
}
}
else
{
if(thePackingString != NULL)
{
snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
}
}
}
}
break;
case kAudioFormatAC3:
strlcpy(outName, "AC-3", sizeof(outName));
break;
case kAudioFormat60958AC3:
strlcpy(outName, "AC-3 for SPDIF", sizeof(outName));
break;
default:
CACopy4CCToCString(outName, inDescription.mFormatID);
break;
};
}
#if CoreAudio_Debug
#include "CALogMacros.h"
void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
{
PrintFloat (" Sample Rate: ", inDesc.mSampleRate);
Print4CharCode (" Format ID: ", inDesc.mFormatID);
PrintHex (" Format Flags: ", inDesc.mFormatFlags);
PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket);
PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket);
PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame);
PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame);
PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel);
}
#endif
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
bool theAnswer = false;
bool isDone = false;
// note that if either side is 0, that field is skipped
// format ID is the first order sort
if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
{
if(x.mFormatID != y.mFormatID)
{
// formats are sorted numerically except that linear
// PCM is always first
if(x.mFormatID == kAudioFormatLinearPCM)
{
theAnswer = true;
}
else if(y.mFormatID == kAudioFormatLinearPCM)
{
theAnswer = false;
}
else
{
theAnswer = x.mFormatID < y.mFormatID;
}
isDone = true;
}
}
// mixable is always better than non-mixable for linear PCM and should be the second order sort item
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
{
if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
{
theAnswer = true;
isDone = true;
}
else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
{
theAnswer = false;
isDone = true;
}
}
// floating point vs integer for linear PCM only
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
{
if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
{
// floating point is better than integer
theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
isDone = true;
}
}
// bit depth
if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
{
if(x.mBitsPerChannel != y.mBitsPerChannel)
{
// deeper bit depths are higher quality
theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
isDone = true;
}
}
// sample rate
if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
{
if(fnotequal(x.mSampleRate, y.mSampleRate))
{
// higher sample rates are higher quality
theAnswer = x.mSampleRate < y.mSampleRate;
isDone = true;
}
}
// number of channels
if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
{
if(x.mChannelsPerFrame != y.mChannelsPerFrame)
{
// more channels is higher quality
theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
//isDone = true;
}
}
return theAnswer;
}
static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
UInt32 xFlags = x.mFormatFlags;
UInt32 yFlags = y.mFormatFlags;
// match wildcards
if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
return true;
if (x.mFormatID == kAudioFormatLinearPCM)
{
// knock off the all clear flag
xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
// if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
}
// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
}
// if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
}
if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
}
// if the number of channels is 1, we don't care about non-interleavedness
if (x.mChannelsPerFrame == 1 && y.mChannelsPerFrame == 1) {
xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
}
}
return xFlags == yFlags;
}
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
// the semantics for equality are:
// 1) Values must match exactly -- except for PCM format flags, see above.
// 2) wildcard's are ignored in the comparison
#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
return
// check the sample rate
(fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
// check the format ids
&& MATCH(mFormatID)
// check the format flags
&& MatchFormatFlags(x, y)
// check the bytes per packet
&& MATCH(mBytesPerPacket)
// check the frames per packet
&& MATCH(mFramesPerPacket)
// check the bytes per frame
&& MATCH(mBytesPerFrame)
// check the channels per frame
&& MATCH(mChannelsPerFrame)
// check the channels per frame
&& MATCH(mBitsPerChannel) ;
}
bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const
{
if (interpretingWildcards)
return *this == other;
return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0;
}
bool SanityCheck(const AudioStreamBasicDescription& x)
{
// This function returns false if there are sufficiently insane values in any field.
// It is very conservative so even some very unlikely values will pass.
// This is just meant to catch the case where the data from a file is corrupted.
return
(x.mSampleRate >= 0.)
&& (x.mSampleRate < 3e6) // SACD sample rate is 2.8224 MHz
&& (x.mBytesPerPacket < 1000000)
&& (x.mFramesPerPacket < 1000000)
&& (x.mBytesPerFrame < 1000000)
&& (x.mChannelsPerFrame <= 1024)
&& (x.mBitsPerChannel <= 1024)
&& (x.mFormatID != 0)
&& !(x.mFormatID == kAudioFormatLinearPCM && (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame));
}
bool CAStreamBasicDescription::FromText(const char *inTextDesc, AudioStreamBasicDescription &fmt)
{
const char *p = inTextDesc;
memset(&fmt, 0, sizeof(fmt));
bool isPCM = true; // until proven otherwise
UInt32 pcmFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
if (p[0] == '-') // previously we required a leading dash on PCM formats
++p;
if (p[0] == 'B' && p[1] == 'E') {
pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
p += 2;
} else if (p[0] == 'L' && p[1] == 'E') {
p += 2;
} else {
// default is native-endian
#if TARGET_RT_BIG_ENDIAN
pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
}
if (p[0] == 'F') {
pcmFlags = (pcmFlags & ~kAudioFormatFlagIsSignedInteger) | kAudioFormatFlagIsFloat;
++p;
} else {
if (p[0] == 'U') {
pcmFlags &= ~kAudioFormatFlagIsSignedInteger;
++p;
}
if (p[0] == 'I')
++p;
else {
// it's not PCM; presumably some other format (NOT VALIDATED; use AudioFormat for that)
isPCM = false;
p = inTextDesc; // go back to the beginning
char buf[4] = { ' ',' ',' ',' ' };
for (int i = 0; i < 4; ++i) {
if (*p != '\\') {
if ((buf[i] = *p++) == '\0') {
// special-case for 'aac'
if (i != 3) return false;
--p; // keep pointing at the terminating null
buf[i] = ' ';
break;
}
} else {
// "\xNN" is a hex byte
if (*++p != 'x') return false;
int x;
if (sscanf(++p, "%02X", &x) != 1) return false;
buf[i] = x;
p += 2;
}
}
if (strchr("-@/#", buf[3])) {
// further special-casing for 'aac'
buf[3] = ' ';
--p;
}
fmt.mFormatID = CFSwapInt32BigToHost(*(UInt32 *)buf);
}
}
if (isPCM) {
fmt.mFormatID = kAudioFormatLinearPCM;
fmt.mFormatFlags = pcmFlags;
fmt.mFramesPerPacket = 1;
fmt.mChannelsPerFrame = 1;
int bitdepth = 0, fracbits = 0;
while (isdigit(*p))
bitdepth = 10 * bitdepth + *p++ - '0';
if (*p == '.') {
++p;
if (!isdigit(*p)) {
fprintf(stderr, "Expected fractional bits following '.'\n");
goto Bail;
}
while (isdigit(*p))
fracbits = 10 * fracbits + *p++ - '0';
bitdepth += fracbits;
fmt.mFormatFlags |= (fracbits << kLinearPCMFormatFlagsSampleFractionShift);
}
fmt.mBitsPerChannel = bitdepth;
fmt.mBytesPerPacket = fmt.mBytesPerFrame = (bitdepth + 7) / 8;
if (bitdepth & 7) {
// assume unpacked. (packed odd bit depths are describable but not supported in AudioConverter.)
fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsPacked;
// alignment matters; default to high-aligned. use ':L_' for low.
fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
}
}
if (*p == '@') {
++p;
while (isdigit(*p))
fmt.mSampleRate = 10 * fmt.mSampleRate + (*p++ - '0');
}
if (*p == '/') {
UInt32 flags = 0;
while (true) {
char c = *++p;
if (c >= '0' && c <= '9')
flags = (flags << 4) | (c - '0');
else if (c >= 'A' && c <= 'F')
flags = (flags << 4) | (c - 'A' + 10);
else if (c >= 'a' && c <= 'f')
flags = (flags << 4) | (c - 'a' + 10);
else break;
}
fmt.mFormatFlags = flags;
}
if (*p == '#') {
++p;
while (isdigit(*p))
fmt.mFramesPerPacket = 10 * fmt.mFramesPerPacket + (*p++ - '0');
}
if (*p == ':') {
++p;
fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsPacked;
if (*p == 'L')
fmt.mFormatFlags &= ~kLinearPCMFormatFlagIsAlignedHigh;
else if (*p == 'H')
fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
else
goto Bail;
++p;
int bytesPerFrame = 0;
while (isdigit(*p))
bytesPerFrame = 10 * bytesPerFrame + (*p++ - '0');
fmt.mBytesPerFrame = fmt.mBytesPerPacket = bytesPerFrame;
}
if (*p == ',') {
++p;
int ch = 0;
while (isdigit(*p))
ch = 10 * ch + (*p++ - '0');
fmt.mChannelsPerFrame = ch;
if (*p == 'D') {
++p;
if (fmt.mFormatID != kAudioFormatLinearPCM) {
fprintf(stderr, "non-interleaved flag invalid for non-PCM formats\n");
goto Bail;
}
fmt.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
} else {
if (*p == 'I') ++p; // default
if (fmt.mFormatID == kAudioFormatLinearPCM)
fmt.mBytesPerPacket = fmt.mBytesPerFrame *= ch;
}
}
if (*p != '\0') {
fprintf(stderr, "extra characters at end of format string: %s\n", p);
goto Bail;
}
return true;
Bail:
fprintf(stderr, "Invalid format string: %s\n", inTextDesc);
fprintf(stderr, "Syntax of format strings is: \n");
return false;
}
const char *CAStreamBasicDescription::sTextParsingUsageString =
"format[@sample_rate_hz][/format_flags][#frames_per_packet][:LHbytesPerFrame][,channelsDI].\n"
"Format for PCM is [-][BE|LE]{F|I|UI}{bitdepth}; else a 4-char format code (e.g. aac, alac).\n";

View File

@ -1,409 +0,0 @@
/*
File: CAStreamBasicDescription.h
Abstract: Part of CoreAudio Utility Classes
Version: 1.2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2013 Apple Inc. All Rights Reserved.
*/
#ifndef __CAStreamBasicDescription_h__
#define __CAStreamBasicDescription_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreFoundation/CoreFoundation.h>
#else
#include "CoreAudioTypes.h"
#include "CoreFoundation.h"
#endif
#include "CADebugMacros.h"
#include <string.h> // for memset, memcpy
#include <stdio.h> // for FILE *
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
extern char *CAStringForOSType (OSType t, char *writeLocation);
// define Leopard specific symbols for backward compatibility if applicable
#if COREAUDIOTYPES_VERSION < 1050
typedef Float32 AudioSampleType;
enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
#endif
#if COREAUDIOTYPES_VERSION < 1051
typedef Float32 AudioUnitSampleType;
enum {
kLinearPCMFormatFlagsSampleFractionShift = 7,
kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
};
#endif
// define the IsMixable format flag for all versions of the system
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
#else
enum { kIsNonMixableFlag = (1L << 6) };
#endif
//=============================================================================
// CAStreamBasicDescription
//
// This is a wrapper class for the AudioStreamBasicDescription struct.
// It adds a number of convenience routines, but otherwise adds nothing
// to the footprint of the original struct.
//=============================================================================
class CAStreamBasicDescription :
public AudioStreamBasicDescription
{
// Constants
public:
static const AudioStreamBasicDescription sEmpty;
enum CommonPCMFormat {
kPCMFormatOther = 0,
kPCMFormatFloat32 = 1,
kPCMFormatInt16 = 2,
kPCMFormatFixed824 = 3
};
// Construction/Destruction
public:
CAStreamBasicDescription();
CAStreamBasicDescription(const AudioStreamBasicDescription &desc);
CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
UInt32 inBitsPerChannel, UInt32 inFormatFlags);
CAStreamBasicDescription( double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) {
unsigned wordsize;
mSampleRate = inSampleRate;
mFormatID = kAudioFormatLinearPCM;
mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
mFramesPerPacket = 1;
mChannelsPerFrame = inNumChannels;
mBytesPerFrame = mBytesPerPacket = 0;
mReserved = 0;
switch (pcmf) {
default:
return;
case kPCMFormatFloat32:
wordsize = 4;
mFormatFlags |= kAudioFormatFlagIsFloat;
break;
case kPCMFormatInt16:
wordsize = 2;
mFormatFlags |= kAudioFormatFlagIsSignedInteger;
break;
case kPCMFormatFixed824:
wordsize = 4;
mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift);
break;
}
mBitsPerChannel = wordsize * 8;
if (inIsInterleaved)
mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels;
else {
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
mBytesPerFrame = mBytesPerPacket = wordsize;
}
}
// Assignment
CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
void SetFrom(const AudioStreamBasicDescription &desc)
{
memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
}
bool FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); }
static bool FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc);
// return true if parsing was successful
static const char *sTextParsingUsageString;
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// interrogation
bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
bool PackednessIsSignificant() const
{
Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
return (SampleWordSize() << 3) != mBitsPerChannel;
}
bool AlignmentIsSignificant() const
{
return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
}
bool IsInterleaved() const
{
return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
}
bool IsSignedInteger() const
{
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger);
}
bool IsFloat() const
{
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat);
}
bool IsNativeEndian() const
{
return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
}
// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
UInt32 NumberChannels() const { return mChannelsPerFrame; }
UInt32 SampleWordSize() const {
return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0;
}
UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
UInt32 BytesToFrames(UInt32 nbytes) const {
Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
return nbytes / mBytesPerFrame;
}
bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
{
return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
}
bool IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const
{ // return true if it's a valid PCM format.
outFormat = kPCMFormatOther;
// trap out patently invalid formats.
if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0)
return false;
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
if (outIsInterleaved != NULL) *outIsInterleaved = interleaved;
unsigned wordsize = mBytesPerFrame;
if (interleaved) {
if (wordsize % mChannelsPerFrame != 0) return false;
wordsize /= mChannelsPerFrame;
}
if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian
&& wordsize * 8 == mBitsPerChannel) {
// packed and native endian, good
if (mFormatFlags & kLinearPCMFormatFlagIsFloat) {
// float: reject nonsense bits
if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
return false;
if (wordsize == 4)
outFormat = kPCMFormatFloat32;
} else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
// signed int
unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
if (wordsize == 4 && fracbits == 24)
outFormat = kPCMFormatFixed824;
else if (wordsize == 2 && fracbits == 0)
outFormat = kPCMFormatInt16;
}
}
return true;
}
bool IsCommonFloat32(bool *outIsInterleaved=NULL) const {
CommonPCMFormat fmt;
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32;
}
bool IsCommonFixed824(bool *outIsInterleaved=NULL) const {
CommonPCMFormat fmt;
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824;
}
bool IsCommonInt16(bool *outIsInterleaved=NULL) const {
CommonPCMFormat fmt;
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16;
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// manipulation
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
{
mFormatID = kAudioFormatLinearPCM;
int sampleSize = SizeOf32(AudioSampleType);
mFormatFlags = kAudioFormatFlagsCanonical;
mBitsPerChannel = 8 * sampleSize;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
else {
mBytesPerPacket = mBytesPerFrame = sampleSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
bool IsCanonical() const
{
if (mFormatID != kAudioFormatLinearPCM) return false;
UInt32 reqFormatFlags;
UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask);
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
unsigned sampleSize = SizeOf32(AudioSampleType);
reqFormatFlags = kAudioFormatFlagsCanonical;
UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
return ((mFormatFlags & flagsMask) == reqFormatFlags
&& mBitsPerChannel == 8 * sampleSize
&& mFramesPerPacket == 1
&& mBytesPerFrame == reqFrameSize
&& mBytesPerPacket == reqFrameSize);
}
void SetAUCanonical(UInt32 nChannels, bool interleaved)
{
mFormatID = kAudioFormatLinearPCM;
#if CA_PREFER_FIXED_POINT
mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
#else
mFormatFlags = kAudioFormatFlagsCanonical;
#endif
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
else {
mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
// alter an existing format
{
Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
if (wordSize == 0)
wordSize = (mBitsPerChannel + 7) / 8;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved) {
mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
} else {
mBytesPerPacket = mBytesPerFrame = wordSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// other
bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
void Print() const {
Print (stdout);
}
void Print(FILE* file) const {
PrintFormat (file, "", "AudioStreamBasicDescription:");
}
void PrintFormat(FILE *f, const char *indent, const char *name) const {
char buf[256];
fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
}
void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
char buf[256];
fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
}
char * AsString(char *buf, size_t bufsize) const;
static void Print (const AudioStreamBasicDescription &inDesc)
{
CAStreamBasicDescription desc(inDesc);
desc.Print ();
}
OSStatus Save(CFPropertyListRef *outData) const;
OSStatus Restore(CFPropertyListRef &inData);
// Operations
static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
static void NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription);
static void ResetFormat(AudioStreamBasicDescription& ioDescription);
static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false);
#if CoreAudio_Debug
static void PrintToLog(const AudioStreamBasicDescription& inDesc);
#endif
};
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
#endif
bool SanityCheck(const AudioStreamBasicDescription& x);
#endif // __CAStreamBasicDescription_h__

View File

@ -1,18 +0,0 @@
//
// API.h
// eqMac2
//
// Created by Romans Kisils on 14/05/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "AFNetworking.h"
#import "Constants.h"
#import "Utilities.h"
#import "Storage.h"
@interface API : NSObject
+(void)startPinging;
+(void)getPromotionWithCallback: (void (^)(id _Nullable resp, NSError * _Nullable err)) cb;
@end

View File

@ -1,67 +0,0 @@
//
// API.m
// eqMac2
//
// Created by Romans Kisils on 14/05/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "API.h"
@implementation API
+(void)startPinging{
[self ping];
[Utilities executeBlock:^{ [self ping]; } every:300];
}
+(void)ping{
NSMutableDictionary *user = [[NSMutableDictionary alloc] init];
[user setObject:[Utilities getMacModel] forKey:@"model"];
[user setObject:[Utilities getOSXVersion] forKey:@"osx_version"];
[user setObject:[Utilities getAppVersion] forKey:@"app_version"];
[self apiRequestWithMethod:@"POST"
andEndPoint:[NSString stringWithFormat:@"/user/%@", [Storage getUUID]]
andBody:user
andCallback: nil];
}
+(void)getPromotionWithCallback: (void (^)(id _Nullable resp, NSError * _Nullable err)) cb{
[self apiRequestWithMethod:@"GET" andEndPoint:@"/promotion" andBody:nil andCallback: cb];
}
+(void)apiRequestWithMethod:(NSString *)method andEndPoint:(NSString *)endpoint andBody:(id)body andCallback: (void (^)(id _Nullable resp, NSError * _Nullable err)) cb{
AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//Set Headers
http.requestSerializer = [AFJSONRequestSerializer serializer];
[http.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//Construct URL
NSString *url = [API_URL stringByAppendingString:endpoint];
id sucCB = ^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if(cb)
cb(responseObject, nil);
};
id errCB = ^(NSURLSessionDataTask * _Nullable task, NSError * _Nullable error) {
if(cb)
cb(nil, error);
};
if([method isEqualToString:@"GET"]){
[http GET:url parameters:nil progress:nil success: sucCB failure: errCB];
}else if([method isEqualToString:@"POST"]){
[http POST:url parameters:body progress:nil success: sucCB failure: errCB];
}else{
if(cb)
cb(nil, [NSError errorWithDomain:@"Invalid Method" code:401 userInfo:nil]);
}
}
@end

View File

@ -1,21 +0,0 @@
//
// AppDelegate.h
// eqMac2
//
// Created by Roman on 08/11/2015.
// Copyright © 2015 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "EQViewController.h"
#import "EQPromotionWindowController.h"
#import "NSAppEventCatcher.h"
#import "Storage.h"
#import "Utilities.h"
#import "eqMacStatusItemView.h"
#import "API.h"
#import "Devices.h"
@interface AppDelegate : NSObject <NSApplicationDelegate, NSPopoverDelegate>
@end

View File

@ -1,232 +0,0 @@
//
// AppDelegate.m
// eqMac2
//
// Created by Roman on 08/11/2015.
// Copyright © 2015 bitgapp. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@property (strong) NSStatusItem *statusBar;
@end
//Views
EQViewController *eqVC;
eqMacStatusItemView *statusItemView;
//Windows
NSPopover *eqPopover;
NSEvent *eqPopoverTransiencyMonitor;
NSTimer *deviceChangeWatcher;
NSTimer *deviceActivityWatcher;
EQPromotionWindowController *promotionWindowController;
NSRunningApplication *focusedApplication;
@implementation AppDelegate
#pragma mark Initialization
- (id)init {
[NSApp activateIgnoringOtherApps:NO];
[self setupStatusBar];
return self;
}
-(void)setupStatusBar{
statusItemView = [[eqMacStatusItemView alloc] init];
statusItemView.target = self;
statusItemView.action = @selector(openEQ); //Open EQ View on Left Click
statusItemView.rightAction = @selector(openEQ); //Open EQ on Right Click
_statusBar = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
[_statusBar setView:statusItemView];
statusItemView.image = [NSImage imageNamed: [Utilities isDarkMode] ? @"statusItemLight" : @"statusItemDark"];
}
-(void)applicationDidFinishLaunching:(NSNotification *)notification{
NSNotificationCenter *observer = [NSNotificationCenter defaultCenter];
[observer addObserver:self selector:@selector(quitApplication) name:@"closeApp" object:nil];
[observer addObserver:self selector:@selector(closePopover) name:@"escapePressed" object:nil];
[observer addObserver:self selector:@selector(readjustPopover) name:@"readjustPopover" object:nil];
[self checkAndInstallDriver];
[self startHelperIfNeeded];
[Storage load];
[Utilities executeBlock:^{ [Storage save]; } every: 60];
eqVC = [[EQViewController alloc] initWithNibName:@"EQViewController" bundle:nil];
eqPopover = [[NSPopover alloc] init];
[eqPopover setDelegate:self];
[eqPopover setContentViewController:eqVC];
[eqPopover setBehavior:NSPopoverBehaviorTransient];
if([Storage getAppAlreadyLaunchedBefore]){
promotionWindowController = [[EQPromotionWindowController alloc] initWithWindowNibName:@"EQPromotionWindowController"];
[promotionWindowController window];
}
//Send anonymous analytics data to the API
[API startPinging];
[self startWatchingDeviceChanges];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(wakeUpFromSleep) name:NSWorkspaceDidWakeNotification object:NULL];
}
-(void)checkAndInstallDriver{
if(![Devices eqMacDriverInstalled]){
//Install only the new driver
switch([Utilities showAlertWithTitle:@"eqMac2 Requires a Driver Update"
andMessage:@"In order to install the driver, the app will ask for your system password."
andButtons:@[@"Install", @"Quit"]]){
case NSAlertFirstButtonReturn:{
if([Utilities runShellScriptWithName:@"install_driver"]){
[NSThread sleepForTimeInterval: .1];
if (![Devices eqMacDriverInstalled]) {
[Utilities runAppleScriptWithName:@"open_security_settings"];
switch([Utilities showAlertWithTitle:@"Problem installing the Driver"
andMessage:@"Most likely your Security settings don't allow non-Appstore apps to be installed with drivers.\nWe have openned your System Preferences.\nDown where it says \"Allow apps downloaded from:\"\nTry to switch to \"App Store and identified developers\"\nAnd then try to install the driver again..."
andButtons:@[@"I changed my settings, try to install again..."]]){
case NSAlertFirstButtonReturn: {
if([Utilities runShellScriptWithName:@"install_driver"]){
[NSThread sleepForTimeInterval: .1];
if (![Devices eqMacDriverInstalled]) {
switch([Utilities showAlertWithTitle:@"Still a problem installing the Driver"
andMessage:@"Please restart your Mac and try to run eqMac2 again.\nIf you have restarted and retried already and it still doesn't work, \nYou can try to resolve the issue by chatting with the developer, or quit eqMac now"
andButtons:@[@"Chat with the developer", @"Quit eqMac2"]]){
case NSAlertFirstButtonReturn: {
[Utilities openBrowserWithURL: HELP_URL];
}
default: {
return [self quitApplication];
}
}
} else {
return [self checkAndInstallDriver];
}
} else {
return [self checkAndInstallDriver];
}
}
default: {
[self quitApplication];
}
}
}
} else {
[self checkAndInstallDriver];
}
break;
}
default :{
[self quitApplication];
break;
}
}
}
}
-(void)startHelperIfNeeded{
NSString *helperBundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/Resources/eqMac2Helper.app"];
[Utilities setLaunchOnLogin:YES forBundlePath: helperBundlePath];
if (![Utilities appWithBundleIdentifierIsRunning: HELPER_BUNDLE_IDENTIFIER]) {
[[NSWorkspace sharedWorkspace] launchApplication: helperBundlePath];
}
}
-(void)startWatchingDeviceChanges{
deviceChangeWatcher = [Utilities executeBlock:^{
AudioDeviceID selectedDeviceID = [Devices getCurrentDeviceID];
if(selectedDeviceID != [Devices getEQMacDeviceID] && [Devices getIsAliveForDeviceID:selectedDeviceID]){
[EQHost createEQEngineWithOutputDevice: selectedDeviceID];
[self startWatchingActivityOfDeviceWithID:selectedDeviceID];
}
} every:.1];
}
-(void)startWatchingActivityOfDeviceWithID:(AudioDeviceID)ID{
deviceActivityWatcher = [Utilities executeBlock:^{
if(![Devices getIsAliveForDeviceID:ID]){
[EQHost deleteEQEngine];
[deviceActivityWatcher invalidate];
deviceActivityWatcher = nil;
}
} every:1];
}
-(void)wakeUpFromSleep{
[deviceChangeWatcher invalidate];
deviceChangeWatcher = nil;
[EQHost deleteEQEngine];
[Devices switchToOutputDeviceWithID:[EQHost getSelectedOutputDeviceID]];
//delay the start a little so os has time to catchup with the Audio Processing
[Utilities executeBlock:^{
[self startWatchingDeviceChanges];
} after:3];
}
- (void)openEQ{
if([eqPopover isShown]){
[self closePopover];
}else{
[eqPopover showRelativeToRect:statusItemView.bounds ofView:statusItemView preferredEdge:NSMaxYEdge];
NSWindow *popoverWindow = eqPopover.contentViewController.view.window;
[popoverWindow.parentWindow removeChildWindow:popoverWindow];
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
if (eqPopoverTransiencyMonitor == nil) {
eqPopoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSKeyUpMask) handler:^(NSEvent* event) {
[NSEvent removeMonitor:eqPopoverTransiencyMonitor];
eqPopoverTransiencyMonitor = nil;
[self closePopover];
}];
}
}
}
-(void)popoverWillShow:(NSNotification *)notification{
focusedApplication = [[NSWorkspace sharedWorkspace] frontmostApplication];
[[NSNotificationCenter defaultCenter] postNotificationName:@"popoverWillOpen" object:nil];
}
-(void)popoverDidShow:(NSNotification *)notification{
[self readjustPopover];
}
-(void)readjustPopover{
[eqPopover setContentSize: eqPopover.contentViewController.view.frame.size];
}
-(void)popoverWillClose:(NSNotification *)notification{
[statusItemView setHighlightState:NO];
}
-(void)closePopover{
[eqPopover close];
if (focusedApplication) {
[focusedApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];
focusedApplication = nil;
}
}
- (void)quitApplication{
[NSApp terminate:nil];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
[self tearDownApplication];
}
-(void)tearDownApplication{
[Storage save];
[EQHost deleteEQEngine];
}
@end

View File

@ -1,22 +0,0 @@
#import <Foundation/Foundation.h>
#ifndef Constants_h
#define Constants_h
extern NSString * const HELPER_BUNDLE_IDENTIFIER;
extern NSString * const DRIVER_UID;
extern NSString * const API_URL;
extern NSString * const APP_URL;
extern NSString * const SUPPORT_URL;
extern NSString * const HELP_URL;
extern Float32 const FULL_VOLUME_STEP;
extern Float32 const QUARTER_VOLUME_STEP;
extern BOOL const LOG;
@interface Constants : NSObject
+(NSArray*)getFrequenciesForBandMode:(NSString*)bandMode;
@end
#endif /* Constants_h */

View File

@ -1,193 +0,0 @@
#import <Foundation/Foundation.h>
#import "Constants.h"
NSString * const HELPER_BUNDLE_IDENTIFIER = @"com.bitgapp.eqMac2Helper";
NSString * const DRIVER_UID = @"EQMAC2.1_DRIVER_ENGINE";
NSString * const API_URL = @"https://eqmac-api.bitgapp.com";
NSString * const APP_URL = @"https://bitgapp.com/eqmac/";
NSString * const SUPPORT_URL = @"https://bitgapp.com/eqmac/#/donate";
NSString * const HELP_URL = @"https://go.crisp.chat/chat/embed/?website_id=d43e2906-97e3-4c50-82ea-6fa04383b983";
Float32 const FULL_VOLUME_STEP = 0.0625;
Float32 const QUARTER_VOLUME_STEP = 0.015625;
BOOL const LOG = YES;
@implementation Constants
+(NSArray*)getFrequenciesForBandMode:(NSString*)bandMode{
NSDictionary *frequencies = @{
@"10": @[
@{
@"frequency": @32,
@"label": @"32"
},
@{
@"frequency": @64,
@"label": @"64"
},
@{
@"frequency": @125,
@"label": @"125"
},
@{
@"frequency": @250,
@"label": @"250"
},
@{
@"frequency": @500,
@"label": @"500"
},
@{
@"frequency": @1000,
@"label": @"1K"
},
@{
@"frequency": @2000,
@"label": @"2K"
},
@{
@"frequency": @4000,
@"label": @"4K"
},
@{
@"frequency": @8000,
@"label": @"8K"
},
@{
@"frequency": @16000,
@"label": @"16K"
}
],
@"31": @[
@{
@"frequency": @20,
@"label": @"20"
},
@{
@"frequency": @25,
@"label": @"25"
},
@{
@"frequency": @31.5,
@"label": @"31.5"
},
@{
@"frequency": @40,
@"label": @"40"
},
@{
@"frequency": @50,
@"label": @"50"
},
@{
@"frequency": @63,
@"label": @"63"
},
@{
@"frequency": @80,
@"label": @"80"
},
@{
@"frequency": @100,
@"label": @"100"
},
@{
@"frequency": @125,
@"label": @"125"
},
@{
@"frequency": @160,
@"label": @"160"
},
@{
@"frequency": @200,
@"label": @"200"
},
@{
@"frequency": @250,
@"label": @"250"
},
@{
@"frequency": @315,
@"label": @"315"
},
@{
@"frequency": @400,
@"label": @"400"
},
@{
@"frequency": @500,
@"label": @"500"
},
@{
@"frequency": @630,
@"label": @"630"
},
@{
@"frequency": @800,
@"label": @"800"
},
@{
@"frequency": @1000,
@"label": @"1K"
},
@{
@"frequency": @1250,
@"label": @"1.25K"
},
@{
@"frequency": @1600,
@"label": @"1.6K"
},
@{
@"frequency": @2000,
@"label": @"2K"
},
@{
@"frequency": @2500,
@"label": @"2.5K"
},
@{
@"frequency": @3150,
@"label": @"3.15K"
},
@{
@"frequency": @4000,
@"label": @"4K"
},
@{
@"frequency": @5000,
@"label": @"5K"
},
@{
@"frequency": @6300,
@"label": @"6.3K"
},
@{
@"frequency": @8000,
@"label": @"8K"
},
@{
@"frequency": @10000,
@"label": @"10K"
},
@{
@"frequency": @12500,
@"label": @"12.5K"
},
@{
@"frequency": @16000,
@"label": @"16K"
},
@{
@"frequency": @20000,
@"label": @"20K"
}
]
};
return [frequencies objectForKey: bandMode];
}
@end

View File

@ -1,53 +0,0 @@
//
// Devices.h
// eqMac
//
// Created by Romans Kisils on 12/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#define checkErr( err) \
if(err) {\
OSStatus error = static_cast<OSStatus>(err);\
fprintf(stdout, "EQEngine Error: %ld -> %s: %d\n", (long)error,\
__FILE__, \
__LINE__\
);\
fflush(stdout);\
return err; \
}
#import <Foundation/Foundation.h>
#import "AudioDevice.h"
#import "Constants.h"
#import "Utilities.h"
#import "EQHost.h"
@interface Devices : NSObject
+(NSArray*)getAllDevices;
+(NSArray*)getAllUsableDevices;
+(AudioDeviceID)getCurrentDeviceID;
+(AudioDeviceID)getEQMacDeviceID;
+(AudioDeviceID)getBuiltInDeviceID;
+(AudioDeviceID)getVolumeControllerDeviceID;
+(void)switchToSystemDeviceWithID:(AudioDeviceID)ID;
+(void)switchToOutputDeviceWithID:(AudioDeviceID)ID;
+(NSString*)getDeviceNameByID:(UInt32)ID;
+(Float32)getOutputVolumeForDeviceID:(AudioDeviceID)ID;
+(Float32)getInputBalanceForDeviceID:(AudioDeviceID)ID;
+(BOOL)getIsMutedForDeviceID:(AudioDeviceID)ID;
+(BOOL)getIsAliveForDeviceID:(AudioDeviceID)ID;
+(UInt32)getDeviceTransportTypeByID:(AudioDeviceID)ID;
+(AudioDeviceID)getDeviceIDByName:(NSString*)name;
+(BOOL)audioDeviceHasVolumeControls:(AudioDeviceID)ID;
+(void)setOutputVolumeForDeviceID:(AudioDeviceID)ID to:(Float32)volume;
+(void)setInputBalanceForDeviceID:(AudioDeviceID)ID to:(Float32)balance;
+(void)setDevice:(AudioDeviceID)ID toMuted:(BOOL)condition;
+(BOOL)eqMacDriverInstalled;
+(BOOL)deviceIsBuiltIn:(AudioDeviceID)ID;
@end

View File

@ -1,496 +0,0 @@
//
// Devices.m
// eqMac
//
// Created by Romans Kisils on 12/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import "Devices.h"
@implementation Devices
static AudioDeviceID eqMacDeviceID;
static AudioDeviceID builtInDeviceID;
typedef enum {
kChannelLeft, kChannelRight, kChannelMaster
} VOLUME_CHANNEL;
#pragma mark -
#pragma mark Getting Devices in Bulk
+(NSArray*)getAllDevices{
//Get device IDs
UInt32 propsize;
//Get devices memory address
AudioObjectPropertyAddress theAddress = {
kAudioHardwarePropertyDevices,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &theAddress, 0, NULL,&propsize); //Get property size of each device
int nDevices = propsize / sizeof(AudioDeviceID); //Calculate the number of devices
AudioDeviceID *devids = new AudioDeviceID[nDevices]; //Allocate new AudioDeviceID array
AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &propsize, devids); //Get the device IDs
//Convert C++ array to NSArray
NSMutableArray *deviceIDs = [[NSMutableArray alloc] init];
for(int i = 0; i < nDevices; ++i){
//Get device transport type
UInt32 transportType = [self getDeviceTransportTypeByID:devids[i]];
if(transportType == kAudioDeviceTransportTypeBuiltIn) {
builtInDeviceID = devids[i];
}
NSString *deviceName = [NSString stringWithFormat:@"%@",[self getDeviceNameByID:devids[i]]];
[deviceIDs addObject:@{@"id": [NSNumber numberWithInt:devids[i]], @"name": deviceName}];
}
delete[] devids;
return deviceIDs;
}
+(NSArray*)getAllUsableDeviceIDs{
//Get device IDs
UInt32 propsize;
AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; //Get devices memory address
AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &theAddress, 0, NULL,&propsize); //Get property size of each device
int nDevices = propsize / sizeof(AudioDeviceID); //Calculate the number of devices
AudioDeviceID *devids = new AudioDeviceID[nDevices]; //Allocate new AudioDeviceID array
AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &propsize, devids); //Get the device IDs
//Convert C++ array to NSArray
NSMutableArray *deviceIDs = [[NSMutableArray alloc] init];
for(int i = 0; i < nDevices; ++i){
//Check if the device is input and dont add the input devices
AudioDeviceID deviceID = devids[i];
if([self deviceIsOutput: deviceID] && deviceID != [self getEQMacDeviceID]) {
[deviceIDs addObject:[NSNumber numberWithInt:deviceID]];
}
}
delete[] devids;
return deviceIDs;
}
+(NSArray*)getAllUsableDevices{
NSArray *deviceIDs = [self getAllUsableDeviceIDs];
NSMutableArray *devices = [[NSMutableArray alloc] init];
for (NSNumber* deviceID in deviceIDs) {
AudioDeviceID ID = [deviceID intValue];
NSString *deviceName = [self getDeviceNameByID: ID];
[devices addObject: @{ @"name": deviceName, @"id": deviceID }];
}
return devices;
}
+(NSArray*)getDevices{
NSArray *devicesIDs = [self getAllUsableDeviceIDs];
NSMutableArray *deviceNames = [[NSMutableArray alloc] init];
for(NSNumber *ID in devicesIDs){
AudioDeviceID id = [ID intValue];
AudioObjectPropertyAddress nameAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, 0 };
char name[64];
UInt32 propsize = sizeof(name);
AudioObjectGetPropertyData(id, &nameAddress, 0, NULL, &propsize, &name);
[deviceNames addObject:@{ @"id":ID, @"name": [NSString stringWithFormat:@"%s",name] }];
}
return deviceNames;
}
#pragma mark -
#pragma mark Getting specific Devices
+(AudioDeviceID)getCurrentDeviceID{
AudioObjectPropertyAddress currentOutputDevicePropertyAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioDeviceID currentOutputDeviceID;
UInt32 currentOutputDeviceIDSize = sizeof(currentOutputDeviceID);
AudioObjectGetPropertyData(kAudioObjectSystemObject,
&currentOutputDevicePropertyAddress,
0, NULL,
&currentOutputDeviceIDSize, &currentOutputDeviceID);
return currentOutputDeviceID;
}
+(AudioDeviceID)getEQMacDeviceID{
if(!eqMacDeviceID){
eqMacDeviceID = [self getDeviceIDWithUID:DRIVER_UID];
}
return eqMacDeviceID;
}
+(AudioDeviceID)getBuiltInDeviceID{
if(!builtInDeviceID){
[self getAllUsableDeviceIDs];
}
return builtInDeviceID;
}
+(AudioDeviceID)getVolumeControllerDeviceID{
AudioDeviceID volumeControlDeviceID = [self getCurrentDeviceID];
if ([EQHost EQEngineExists]) {
AudioDeviceID selectedDeviceID = [EQHost getSelectedOutputDeviceID];
if ([Devices deviceIsBuiltIn: selectedDeviceID]) {
volumeControlDeviceID = [Devices getEQMacDeviceID];
} else {
volumeControlDeviceID = selectedDeviceID;
}
}
return volumeControlDeviceID;
}
#pragma mark -
#pragma mark Device Control
+(void)switchToSystemDeviceWithID:(AudioDeviceID)ID{
AudioObjectPropertyAddress devAddress = { kAudioHardwarePropertyDefaultSystemOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
AudioObjectSetPropertyData(kAudioObjectSystemObject, &devAddress, 0, NULL, sizeof(ID), &ID);
}
+(void)switchToOutputDeviceWithID:(AudioDeviceID)ID{
AudioObjectPropertyAddress devAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeOutput, kAudioObjectPropertyElementMaster };
AudioObjectSetPropertyData(kAudioObjectSystemObject, &devAddress, 0, NULL, sizeof(ID), &ID);
}
#pragma mark -
#pragma mark Get Device Properties
+(Float32)getVolumeForDeviceID:(AudioDeviceID)deviceID andChannel:(VOLUME_CHANNEL)ch andScope:(UInt32)scope{
UInt32 channel;
switch(ch){
case kChannelLeft:{
channel = 1;
break;
}
case kChannelRight:{
channel = 2;
break;
}
case kChannelMaster:{
channel = kAudioObjectPropertyElementMaster;
break;
}
}
AudioObjectPropertyAddress volumePropertyAddress = {
kAudioDevicePropertyVolumeScalar,
scope,
channel
};
Float32 volume;
UInt32 volumeSize = sizeof(volume);
AudioObjectGetPropertyData(deviceID, &volumePropertyAddress,0, NULL, &volumeSize, &volume);
return volume;
}
+(Float32)getOutputVolumeForDeviceID:(AudioDeviceID)deviceID andChannel:(VOLUME_CHANNEL)ch{
return [self getVolumeForDeviceID:deviceID andChannel:ch andScope:kAudioDevicePropertyScopeOutput];
}
+(Float32)getInputVolumeForDeviceID:(AudioDeviceID)deviceID andChannel:(VOLUME_CHANNEL)ch{
return [self getVolumeForDeviceID:deviceID andChannel:ch andScope:kAudioDevicePropertyScopeInput];
}
+(Float32)getOutputVolumeForDeviceID:(AudioDeviceID)ID{
Float32 volume = 0;
if([self audioDeviceHasMasterVolume:ID]){
volume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelMaster];
}else{
Float32 leftVolume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelLeft];
Float32 rightVolume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelRight];
volume = leftVolume > rightVolume ? leftVolume : rightVolume;
}
return volume;
}
+(Float32)getInputVolumeForDeviceID:(AudioDeviceID)ID{
Float32 volume = 0;
if([self audioDeviceHasMasterVolume:ID]){
volume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelMaster];
}else{
Float32 leftVolume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelLeft];
Float32 rightVolume = [self getOutputVolumeForDeviceID:ID andChannel:kChannelRight];
volume = leftVolume > rightVolume ? leftVolume : rightVolume;
}
return volume;
}
+(Float32)getInputBalanceForDeviceID:(AudioDeviceID)ID{
Float32 left = [self getInputVolumeForDeviceID:ID andChannel:kChannelLeft];
Float32 right = [self getInputVolumeForDeviceID:ID andChannel:kChannelRight];
Float32 balance = right - left;
if(isnan(balance)) balance = 0;
return balance;
}
+(BOOL)getIsMutedForDeviceID:(AudioDeviceID)ID{
AudioObjectPropertyAddress mutedAddress;
mutedAddress.mScope = kAudioDevicePropertyScopeOutput;
mutedAddress.mSelector = kAudioDevicePropertyMute;
mutedAddress.mElement = kAudioObjectPropertyElementMaster;
//Check if Master Volume can be muted
if (!AudioObjectHasProperty(ID, &mutedAddress)){
mutedAddress.mElement = 1; //If not fallback to left channel and check again
if (!AudioObjectHasProperty(ID, &mutedAddress)){
mutedAddress.mElement = 2; //If not fallback to right channel and check again
if (!AudioObjectHasProperty(ID, &mutedAddress)){
return false; //If nothing can be muted return false
}
}
}
UInt32 data;
UInt32 dataSize = sizeof(data);
AudioObjectGetPropertyData(ID, &mutedAddress, 0, NULL, &dataSize, &data);
return data == 1;
}
+(BOOL)getIsAliveForDeviceID:(AudioDeviceID)ID{
AudioObjectPropertyAddress mutedAddress;
mutedAddress.mScope = kAudioDevicePropertyScopeOutput;
mutedAddress.mSelector = kAudioDevicePropertyDeviceIsAlive;
mutedAddress.mElement = kAudioObjectPropertyElementMaster;
UInt32 data;
UInt32 dataSize = sizeof(data);
AudioObjectGetPropertyData(ID, &mutedAddress, 0, NULL, &dataSize, &data);
return data == 1;
}
+(BOOL)getIsRunningForDeviceID:(AudioDeviceID)ID{
AudioObjectPropertyAddress mutedAddress;
mutedAddress.mScope = kAudioDevicePropertyScopeOutput;
mutedAddress.mSelector = kAudioDevicePropertyDeviceIsRunning;
mutedAddress.mElement = kAudioObjectPropertyElementMaster;
UInt32 data;
UInt32 dataSize = sizeof(data);
AudioObjectGetPropertyData(ID, &mutedAddress, 0, NULL, &dataSize, &data);
return data == 1;
}
+(AudioDeviceID)getDeviceIDByName:(NSString*)name{
for(NSDictionary *device in [self getDevices]){
if([[device objectForKey:@"name"] isEqualToString:name]){
AudioDeviceID devID = [[device objectForKey:@"id"] intValue];
return devID;
}
}
return -1;
}
+ (AudioDeviceID)getDeviceIDWithUID:(NSString *)uid{
AudioDeviceID myDevice;
AudioValueTranslation trans;
CFStringRef myKnownUID = (__bridge CFStringRef )uid;
trans.mInputData = &myKnownUID;
trans.mInputDataSize = sizeof (CFStringRef);
trans.mOutputData = &myDevice;
trans.mOutputDataSize = sizeof(AudioDeviceID);
UInt32 size = sizeof (AudioValueTranslation);
AudioHardwareGetProperty (kAudioHardwarePropertyDeviceForUID,
&size,
&trans);
return myDevice;
}
+(UInt32)getDeviceTransportTypeByID:(AudioDeviceID)ID{
AudioObjectPropertyAddress transportAddress = { kAudioDevicePropertyTransportType, kAudioObjectPropertyScopeGlobal, 0};
UInt32 transportSize = sizeof(UInt32);
UInt32 transportType = 0;
AudioObjectGetPropertyData(ID, &transportAddress, 0, NULL, &transportSize, &transportType);
return transportType;
}
+(NSString*)getDeviceNameByID:(UInt32)ID{
AudioObjectPropertyAddress nameAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, 0 };
char name[64];
UInt32 propsize = sizeof(name);
AudioObjectGetPropertyData(ID, &nameAddress, 0, NULL, &propsize, &name);
return [NSString stringWithFormat:@"%s", name];
}
#pragma mark -
#pragma mark Set Device Properties
//PRIVATE
+(void)setVolumeForDeviceID:(AudioDeviceID)ID andChannel:(VOLUME_CHANNEL)ch andScope:(UInt32)scope to:(Float32)vol{
UInt32 channel;
if(vol < 0) vol = 0;
switch(ch){
case kChannelLeft:{
channel = 1;
break;
}
case kChannelRight:{
channel = 2;
break;
}
case kChannelMaster:{
channel = kAudioObjectPropertyElementMaster;
break;
}
}
AudioObjectPropertyAddress volumePropertyAddress = {
kAudioDevicePropertyVolumeScalar,
scope,
channel
};
AudioObjectSetPropertyData(ID, &volumePropertyAddress,0, NULL, sizeof(vol), &vol);
}
+(void)setOutputVolumeForDeviceID:(AudioDeviceID)ID andChannel:(VOLUME_CHANNEL)ch to:(Float32)vol{
return [self setVolumeForDeviceID:ID andChannel:ch andScope:kAudioDevicePropertyScopeOutput to:vol];
}
+(void)setInputVolumeForDeviceID:(AudioDeviceID)ID andChannel:(VOLUME_CHANNEL)ch to:(Float32)vol{
return [self setVolumeForDeviceID:ID andChannel:ch andScope:kAudioDevicePropertyScopeInput to:vol];
}
+(void)setDevice:(AudioDeviceID)ID toMuted:(BOOL)condition{
UInt32 mute = condition ? 1 : 0;
AudioObjectPropertyAddress mutedAddress;
mutedAddress.mScope = kAudioDevicePropertyScopeOutput;
mutedAddress.mSelector = kAudioDevicePropertyMute;
//MASTER
mutedAddress.mElement = kAudioObjectPropertyElementMaster;
if (AudioObjectHasProperty(ID, &mutedAddress)){
AudioObjectSetPropertyData(ID, &mutedAddress, 0, NULL, sizeof(mute), &mute);
}
//LEFT
mutedAddress.mElement = 1;
if (AudioObjectHasProperty(ID, &mutedAddress)){
AudioObjectSetPropertyData(ID, &mutedAddress, 0, NULL, sizeof(mute), &mute);
}
//RIGHT
mutedAddress.mElement = 2;
if (AudioObjectHasProperty(ID, &mutedAddress)){
AudioObjectSetPropertyData(ID, &mutedAddress, 0, NULL, sizeof(mute), &mute);
}
}
//PUBLIC
+(BOOL)audioDeviceHasMasterVolume:(AudioDeviceID)ID{
AudioObjectPropertyAddress address;
address.mScope = kAudioDevicePropertyScopeOutput;
address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mElement = kAudioObjectPropertyElementMaster;
return AudioObjectHasProperty(ID, &address);
}
+(BOOL)audioDeviceHasLeftChannelVolume:(AudioDeviceID)ID{
AudioObjectPropertyAddress address;
address.mScope = kAudioDevicePropertyScopeOutput;
address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mElement = kChannelLeft;
return AudioObjectHasProperty(ID, &address);
}
+(BOOL)audioDeviceHasRightChannelVolume:(AudioDeviceID)ID{
AudioObjectPropertyAddress address;
address.mScope = kAudioDevicePropertyScopeOutput;
address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mElement = kChannelRight;
return AudioObjectHasProperty(ID, &address);
}
+(BOOL)audioDeviceHasVolumeControls:(AudioDeviceID)ID{
return ([self audioDeviceHasMasterVolume:ID] || [self audioDeviceHasLeftChannelVolume:ID] || [self audioDeviceHasRightChannelVolume:ID]);
}
//PUBLIC
+(void)setOutputVolumeForDeviceID:(AudioDeviceID)ID to:(Float32)volume{
if([self audioDeviceHasMasterVolume:ID]){
[self setOutputVolumeForDeviceID:ID andChannel:kChannelMaster to:volume];
}else{
[self setOutputVolumeForDeviceID:ID andChannel:kChannelLeft to: volume];
[self setOutputVolumeForDeviceID:ID andChannel:kChannelRight to: volume];
}
[self setDevice:ID toMuted:volume < QUARTER_VOLUME_STEP];
}
//PUBLIC
+(void)setInputBalanceForDeviceID:(AudioDeviceID)ID to:(Float32)balance{
Float32 leftVolume = 1 - balance;
Float32 rightVolume = 1 + balance;
if(leftVolume > 1) leftVolume = 1;
if(rightVolume > 1) rightVolume = 1;
[self setInputVolumeForDeviceID:ID andChannel:kChannelLeft to:leftVolume];
[self setInputVolumeForDeviceID:ID andChannel:kChannelRight to:rightVolume];
}
#pragma mark -
#pragma mark Conditions
+(BOOL)deviceIsInput:(AudioDeviceID)ID{
AudioObjectPropertyAddress propAddress;
propAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeInput, 0 };
UInt32 dataSize = 0;
AudioObjectGetPropertyDataSize(ID, &propAddress, 0, NULL, &dataSize);
UInt32 streamCount = dataSize / sizeof(AudioStreamID);
return (streamCount > 0);
}
+(BOOL)deviceIsOutput:(AudioDeviceID)ID{
AudioObjectPropertyAddress propAddress;
propAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, 0 };
UInt32 dataSize = 0;
AudioObjectGetPropertyDataSize(ID, &propAddress, 0, NULL, &dataSize);
UInt32 streamCount = dataSize / sizeof(AudioStreamID);
return (streamCount > 0);
}
+(BOOL)deviceIsBuiltIn:(AudioDeviceID)ID{
return (ID == [self getEQMacDeviceID] || [self getDeviceTransportTypeByID:ID] == kAudioDeviceTransportTypeBuiltIn);
}
+(BOOL)eqMacDriverInstalled{
AudioDeviceID eqMacDeviceID = [self getEQMacDeviceID];
NSLog(@"%u", (unsigned int)eqMacDeviceID);
return (eqMacDeviceID > 0);
}
@end

View File

@ -1,13 +0,0 @@
//
// EQClickableImageView.h
// eqMac2
//
// Created by Romans Kisils on 15/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface EQClickableImageView : NSImageView
@property SEL clickAction;
@end

View File

@ -1,18 +0,0 @@
//
// EQClickableImageView.m
// eqMac2
//
// Created by Romans Kisils on 15/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "EQClickableImageView.h"
@implementation EQClickableImageView
-(void)mouseDown:(NSEvent *)event{
[self.target performSelectorOnMainThread:self.clickAction withObject:nil waitUntilDone:NO];
}
@end

View File

@ -1,147 +0,0 @@
/*
File: EQEngine.h
Abstract: CAPlayThough Classes.
Version: 1.2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2013 Apple Inc. All Rights Reserved.
*/
#ifndef __EQEngine_H__
#define __EQEngine_H__
#define checkErr( err) \
if(err) {\
OSStatus error = static_cast<OSStatus>(err);\
fprintf(stdout, "EQEngine Error: %ld -> %s: %d\n", (long)error,\
__FILE__, \
__LINE__\
);\
fflush(stdout);\
return err; \
}
#include <CoreAudio/CoreAudio.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
#include "CARingBuffer.h"
#include "AudioDevice.h"
#include "CAStreamBasicDescription.h"
class EQEngine {
public:
EQEngine(AudioDeviceID input, AudioDeviceID output);
~EQEngine();
OSStatus Init(AudioDeviceID input, AudioDeviceID output);
void Cleanup();
OSStatus Start();
OSStatus Stop();
Boolean IsRunning();
void SetEqFrequencies(UInt32 frequencies[], UInt32 count);
void SetEqGains(Float32 gains[], UInt32 count);
Float32* GetEqGains();
AudioDeviceID GetInputDeviceID() { return mInputDevice.mID; }
AudioDeviceID GetOutputDeviceID() { return mOutputDevice.mID; }
AudioDeviceIOProcID mInputIOProcID;
private:
OSStatus SetupGraph(AudioDeviceID out);
OSStatus MakeGraph();
OSStatus SetupAUHAL(AudioDeviceID in);
OSStatus EnableIO();
OSStatus CallbackSetup();
OSStatus SetupBuffers();
OSStatus ResetEqUnits();
void ComputeThruOffset();
static OSStatus InputProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData);
static OSStatus OutputProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData);
OSStatus SetOutputDeviceAsCurrent(AudioDeviceID out);
OSStatus SetInputDeviceAsCurrent(AudioDeviceID in);
AudioUnit mInputUnit;
AudioBufferList *mInputBuffer;
AudioDevice mInputDevice, mOutputDevice;
CARingBuffer *mBuffer;
CAStreamBasicDescription asbd;
//AudioUnits and Graph
AUGraph mGraph;
AUNode mVarispeedNode;
AudioUnit mVarispeedUnit;
AUNode mFormatNode;
AudioUnit mFormatUnit;
AUNode mEqualizerNode1;
AudioUnit mEqualizerUnit1;
AUNode mEqualizerNode2;
AudioUnit mEqualizerUnit2;
AUNode mOutputNode;
AudioUnit mOutputUnit;
//Buffer sample info
Float64 mFirstInputTime;
Float64 mFirstOutputTime;
Float64 mInToOutSampleOffset;
};
#endif //__EQEngine_H__

View File

@ -1,765 +0,0 @@
/*
File: EQEngine.cpp
Abstract: CAPlayThough Classes.
Version: 1.2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2013 Apple Inc. All Rights Reserved.
*/
#include "EQEngine.h"
#pragma mark -- EQEngine
#pragma mark ---Public Methods---
#pragma mark ---EQEngine Methods---
EQEngine::EQEngine(AudioDeviceID input, AudioDeviceID output):
mBuffer(NULL),
mFirstInputTime(-1),
mFirstOutputTime(-1),
mInToOutSampleOffset(0){
OSStatus err = noErr;
err = Init(input,output);
if(err) {
fprintf(stderr,"EQEngine ERROR: Cannot Init EQEngine");
exit(1);
}
}
EQEngine::~EQEngine(){
Cleanup();
}
OSStatus EQEngine::Init(AudioDeviceID input, AudioDeviceID output){
OSStatus err = noErr;
//Note: You can interface to input and output devices with "output" audio units.
//Please keep in mind that you are only allowed to have one output audio unit per graph (AUGraph).
//As you will see, this sample code splits up the two output units. The "output" unit that will
//be used for device input will not be contained in a AUGraph, while the "output" unit that will
//interface the default output device will be in a graph.
//Setup AUHAL for an input device
err = SetupAUHAL(input);
checkErr(err);
//Setup Graph containing Varispeed Unit & Default Output Unit
err = SetupGraph(output);
checkErr(err);
err = SetupBuffers();
checkErr(err);
// the varispeed unit should only be conected after the input and output formats have been set
err = AUGraphConnectNodeInput(mGraph, mVarispeedNode, 0, mFormatNode, 0);
checkErr(err);
err = AUGraphConnectNodeInput(mGraph, mFormatNode, 0, mEqualizerNode1, 0);
checkErr(err);
err = AUGraphConnectNodeInput(mGraph, mEqualizerNode1, 0, mEqualizerNode2, 0);
checkErr(err);
err = AUGraphConnectNodeInput(mGraph, mEqualizerNode2, 0, mOutputNode, 0);
checkErr(err);
err = AUGraphInitialize(mGraph);
checkErr(err);
//Add latency between the two devices
ComputeThruOffset();
return err;
}
void EQEngine::Cleanup(){
//clean up
Stop();
delete mBuffer;
mBuffer = 0;
if(mInputBuffer){
for(UInt32 i = 0; i<mInputBuffer->mNumberBuffers; i++)
free(mInputBuffer->mBuffers[i].mData);
free(mInputBuffer);
mInputBuffer = 0;
}
AudioUnitUninitialize(mInputUnit);
AUGraphClose(mGraph);
DisposeAUGraph(mGraph);
AudioComponentInstanceDispose(mInputUnit);
}
#pragma mark --- Operation---
OSStatus EQEngine::Start()
{
OSStatus err = noErr;
if(!IsRunning()){
//Start pulling for audio data
err = AudioOutputUnitStart(mInputUnit);
checkErr(err);
err = AUGraphStart(mGraph);
checkErr(err);
//reset sample times
mFirstInputTime = -1;
mFirstOutputTime = -1;
}
return err;
}
OSStatus EQEngine::Stop()
{
OSStatus err = noErr;
if(IsRunning()){
//Stop the AUHAL
err = AudioOutputUnitStop(mInputUnit);
checkErr(err);
err = AUGraphStop(mGraph);
checkErr(err);
mFirstInputTime = -1;
mFirstOutputTime = -1;
}
return err;
}
Boolean EQEngine::IsRunning()
{
OSStatus err = noErr;
UInt32 auhalRunning = 0, size = 0;
Boolean graphRunning = false;
size = sizeof(auhalRunning);
if(mInputUnit)
{
err = AudioUnitGetProperty(mInputUnit,
kAudioOutputUnitProperty_IsRunning,
kAudioUnitScope_Global,
0, // input element
&auhalRunning,
&size);
checkErr(err);
}
if(mGraph) {
err = AUGraphIsRunning(mGraph,&graphRunning);
checkErr(err);
}
return (auhalRunning || graphRunning);
}
OSStatus EQEngine::SetOutputDeviceAsCurrent(AudioDeviceID out)
{
UInt32 size = sizeof(AudioDeviceID);;
OSStatus err = noErr;
AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
if(out == kAudioDeviceUnknown) //Retrieve the default output device
{
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &size, &out);
checkErr(err);
}
mOutputDevice.Init(out, false);
//Set the Current Device to the Default Output Unit only if the devices are different
if(out != mInputDevice.mID){
err = AudioUnitSetProperty(mOutputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Output,
0,
&mOutputDevice.mID,
sizeof(mOutputDevice.mID));
}
return err;
}
OSStatus EQEngine::SetInputDeviceAsCurrent(AudioDeviceID in)
{
UInt32 size = sizeof(AudioDeviceID);
OSStatus err = noErr;
AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyDefaultInputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
if(in == kAudioDeviceUnknown) //get the default input device if device is unknown
{
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &size, &in);
checkErr(err);
}
mInputDevice.Init(in, true);
//Set the Current Device to the AUHAL.
//this should be done only after IO has been enabled on the AUHAL.
err = AudioUnitSetProperty(mInputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Input,
0,
&mInputDevice.mID,
sizeof(mInputDevice.mID));
checkErr(err);
return err;
}
Float32 map(Float32 x, Float32 in_min, Float32 in_max, Float32 out_min, Float32 out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
OSStatus EQEngine::ResetEqUnits(){
OSStatus err = noErr;
for (int i = 0; i < 16; i++) {
AudioUnitParameterID frequencyParamID = kAUNBandEQParam_Frequency + i;
err = AudioUnitSetParameter(mEqualizerUnit1, frequencyParamID, kAudioUnitScope_Global, 0, (AudioUnitParameterValue)0, 0);
checkErr(err);
err = AudioUnitSetParameter(mEqualizerUnit2, frequencyParamID, kAudioUnitScope_Global, 0, (AudioUnitParameterValue)0, 0);
checkErr(err);
AudioUnitParameterID bypassBandParamID = kAUNBandEQParam_BypassBand + i;
err = AudioUnitSetParameter(mEqualizerUnit1, bypassBandParamID, kAudioUnitScope_Global, 0, (AudioUnitParameterValue)0, 0);
checkErr(err);
err = AudioUnitSetParameter(mEqualizerUnit2, bypassBandParamID, kAudioUnitScope_Global, 0,(AudioUnitParameterValue) 0, 0);
checkErr(err);
AudioUnitParameterID gainParamID = kAUNBandEQParam_Gain + i;
err = AudioUnitSetParameter(mEqualizerUnit1, gainParamID, kAudioUnitScope_Global, 0, 0, 0);
checkErr(err);
err = AudioUnitSetParameter(mEqualizerUnit2, gainParamID, kAudioUnitScope_Global, 0, 0, 0);
checkErr(err);
}
return err;
}
void EQEngine::SetEqFrequencies(UInt32 *frequencies, UInt32 count){
ResetEqUnits();
for (int i = 0; i < count; i++) {
int incrementor = i;
AudioUnit eqUnit = mEqualizerUnit1;
if (i >= 16) {
incrementor = i - 16;
eqUnit = mEqualizerUnit2;
}
AudioUnitParameterID parameterID = kAUNBandEQParam_Frequency + incrementor;
AudioUnitSetParameter(eqUnit, parameterID, kAudioUnitScope_Global, 0, (AudioUnitParameterValue)frequencies[i], 0);
parameterID = kAUNBandEQParam_BypassBand + incrementor;
AudioUnitSetParameter(eqUnit, parameterID, kAudioUnitScope_Global, 0, (AudioUnitParameterValue)0, 0);
}
}
void EQEngine::SetEqGains(Float32 *gains, UInt32 count){
for (int i = 0; i < count; i++) {
int incrementor = i;
AudioUnit eqUnit = mEqualizerUnit1;
if (i >= 16) {
incrementor = i - 16;
eqUnit = mEqualizerUnit2;
}
AudioUnitParameterID parameterID = kAUNBandEQParam_Gain + incrementor;
AudioUnitSetParameter(eqUnit, parameterID, kAudioUnitScope_Global, 0, map(gains[i], -1.0, 1.0, -24.0, 24.0),0);
}
}
Float32* EQEngine::GetEqGains(){
Float32 *gains = new Float32[32]();
for (int i = 0; i < 32; i++) {
int incrementor = i;
AudioUnit eqUnit = mEqualizerUnit1;
if (i >= 16) {
incrementor = i - 16;
eqUnit = mEqualizerUnit2;
}
AudioUnitParameterID parameterID = kAUNBandEQParam_Gain + incrementor;
AudioUnitGetParameter(eqUnit, parameterID, kAudioUnitScope_Global, 0, &gains[i]);
gains[i] = map(gains[i], -24, 24, -1, 1);
}
return gains;
}
#pragma mark -
#pragma mark --Private methods---
OSStatus EQEngine::SetupGraph(AudioDeviceID out)
{
OSStatus err = noErr;
AURenderCallbackStruct output;
//Make a New Graph
err = NewAUGraph(&mGraph);
checkErr(err);
//Open the Graph, AudioUnits are opened but not initialized
err = AUGraphOpen(mGraph);
checkErr(err);
err = MakeGraph();
checkErr(err);
err = SetOutputDeviceAsCurrent(out);
checkErr(err);
//Tell the output unit not to reset timestamps
//Otherwise sample rate changes will cause sync los
UInt32 startAtZero = 0;
err = AudioUnitSetProperty(mOutputUnit,
kAudioOutputUnitProperty_StartTimestampsAtZero,
kAudioUnitScope_Global,
0,
&startAtZero,
sizeof(startAtZero));
checkErr(err);
output.inputProc = OutputProc;
output.inputProcRefCon = this;
UInt32 nBands = 16;
err = AudioUnitSetProperty(mEqualizerUnit1, kAUNBandEQProperty_NumberOfBands, kAudioUnitScope_Global, 0, &nBands, sizeof(nBands));
checkErr(err);
err = AudioUnitSetProperty(mEqualizerUnit2, kAUNBandEQProperty_NumberOfBands, kAudioUnitScope_Global, 0, &nBands, sizeof(nBands));
checkErr(err);
ResetEqUnits();
AudioUnitSetProperty(mFormatUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &asbd, sizeof(asbd));
err = AudioUnitSetProperty(mVarispeedUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&output,
sizeof(output));
checkErr(err);
return err;
}
OSStatus EQEngine::MakeGraph(){
OSStatus err = noErr;
AudioComponentDescription varispeedDesc,outDesc, eqDesc1, eqDesc2, formatDesc;
//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;
eqDesc1.componentType = kAudioUnitType_Effect;
eqDesc1.componentSubType = kAudioUnitSubType_NBandEQ;
eqDesc1.componentManufacturer = kAudioUnitManufacturer_Apple;
eqDesc1.componentFlags = 0;
eqDesc1.componentFlagsMask = 0;
eqDesc2.componentType = kAudioUnitType_Effect;
eqDesc2.componentSubType = kAudioUnitSubType_NBandEQ;
eqDesc2.componentManufacturer = kAudioUnitManufacturer_Apple;
eqDesc2.componentFlags = 0;
eqDesc2.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
err = AUGraphAddNode(mGraph, &varispeedDesc, &mVarispeedNode);
checkErr(err);
err = AUGraphAddNode(mGraph, &formatDesc, &mFormatNode);
checkErr(err);
err = AUGraphAddNode(mGraph, &eqDesc1, &mEqualizerNode1);
checkErr(err);
err = AUGraphAddNode(mGraph, &eqDesc2, &mEqualizerNode2);
checkErr(err);
err = AUGraphAddNode(mGraph, &outDesc, &mOutputNode);
checkErr(err);
//Get Audio Units from AUGraph node
err = AUGraphNodeInfo(mGraph, mVarispeedNode, NULL, &mVarispeedUnit);
checkErr(err);
err = AUGraphNodeInfo(mGraph, mFormatNode, NULL, &mFormatUnit);
checkErr(err);
err = AUGraphNodeInfo(mGraph, mEqualizerNode1, NULL, &mEqualizerUnit1);
checkErr(err);
err = AUGraphNodeInfo(mGraph, mEqualizerNode2, NULL, &mEqualizerUnit2);
checkErr(err);
err = AUGraphNodeInfo(mGraph, mOutputNode, NULL, &mOutputUnit);
checkErr(err);
// don't connect nodes until the varispeed unit has input and output formats set
return err;
}
OSStatus EQEngine::SetupAUHAL(AudioDeviceID in){
OSStatus err = noErr;
AudioComponent comp;
AudioComponentDescription desc;
//There are several different types of Audio Units.
//Some audio units serve as Outputs, Mixers, or DSP
//units. See AUComponent.h for listing
desc.componentType = kAudioUnitType_Output;
//Every Component has a subType, which will give a clearer picture
//of what this components function will be.
desc.componentSubType = kAudioUnitSubType_HALOutput;
//all Audio Units in AUComponent.h must use
//"kAudioUnitManufacturer_Apple" as the Manufacturer
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
//Finds a component that meets the desc spec's
comp = AudioComponentFindNext(NULL, &desc);
if (comp == NULL) exit (-1);
//gains access to the services provided by the component
err = AudioComponentInstanceNew(comp, &mInputUnit);
checkErr(err);
//AUHAL needs to be initialized before anything is done to it
err = AudioUnitInitialize(mInputUnit);
checkErr(err);
err = EnableIO();
checkErr(err);
err= SetInputDeviceAsCurrent(in);
checkErr(err);
err = CallbackSetup();
checkErr(err);
//Don't setup buffers until you know what the
//input and output device audio streams look like.
err = AudioUnitInitialize(mInputUnit);
return err;
}
OSStatus EQEngine::EnableIO(){
OSStatus err = noErr;
UInt32 enableIO;
///////////////
//ENABLE IO (INPUT)
//You must enable the Audio Unit (AUHAL) for input and disable output
//BEFORE setting the AUHAL's current device.
//Enable input on the AUHAL
enableIO = 1;
err = AudioUnitSetProperty(mInputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1, // input element
&enableIO,
sizeof(enableIO));
checkErr(err);
//disable Output on the AUHAL
enableIO = 1;
err = AudioUnitSetProperty(mInputUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0, //output element
&enableIO,
sizeof(enableIO));
return err;
}
OSStatus EQEngine::CallbackSetup(){
OSStatus err = noErr;
AURenderCallbackStruct input;
input.inputProc = InputProc;
input.inputProcRefCon = this;
//Setup the input callback.
err = AudioUnitSetProperty(mInputUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&input,
sizeof(input));
checkErr(err);
return err;
}
//Allocate Audio Buffer List(s) to hold the data from input.
OSStatus EQEngine::SetupBuffers(){
OSStatus err = noErr;
UInt32 bufferSizeFrames,bufferSizeBytes,propsize;
CAStreamBasicDescription asbd_dev1_in,asbd_dev2_out;
Float64 rate=0;
//Get the size of the IO buffer(s)
UInt32 propertySize = sizeof(bufferSizeFrames);
err = AudioUnitGetProperty(mInputUnit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, &bufferSizeFrames, &propertySize);
checkErr(err);
bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
//Get the Stream Format (Output client side)
propertySize = sizeof(asbd_dev1_in);
err = AudioUnitGetProperty(mInputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &asbd_dev1_in, &propertySize);
checkErr(err);
printf("=====Input DEVICE stream format\n" );
asbd_dev1_in.Print();
//Get the Stream Format (client side)
propertySize = sizeof(asbd);
err = AudioUnitGetProperty(mInputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &asbd, &propertySize);
checkErr(err);
printf("=====current Input (Client) stream format\n");
asbd.Print();
//Get the Stream Format (Output client side)
propertySize = sizeof(asbd_dev2_out);
err = AudioUnitGetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &asbd_dev2_out, &propertySize);
checkErr(err);
printf("=====Output (Device) stream format\n");
asbd_dev2_out.Print();
//////////////////////////////////////
//Set the format of all the AUs to the input/output devices channel count
//For a simple case, you want to set this to the lower of count of the channels
//in the input device vs output device
//////////////////////////////////////
asbd.mChannelsPerFrame =((asbd_dev1_in.mChannelsPerFrame < asbd_dev2_out.mChannelsPerFrame) ?asbd_dev1_in.mChannelsPerFrame :asbd_dev2_out.mChannelsPerFrame) ;
// We must get the sample rate of the input device and set it to the stream format of AUHAL
propertySize = sizeof(Float64);
AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyNominalSampleRate,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyData(mInputDevice.mID, &theAddress, 0, NULL, &propertySize, &rate);
checkErr(err);
asbd.mSampleRate =rate;
propertySize = sizeof(asbd);
//Set the new formats to the AUs...
err = AudioUnitSetProperty(mInputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &asbd, propertySize);
checkErr(err);
err = AudioUnitSetProperty(mVarispeedUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &asbd, propertySize);
checkErr(err);
//Set the correct sample rate for the output device, but keep the channel count the same
propertySize = sizeof(Float64);
err = AudioObjectGetPropertyData(mOutputDevice.mID, &theAddress, 0, NULL, &propertySize, &rate);
checkErr(err);
asbd.mSampleRate =rate;
propertySize = sizeof(asbd);
//Set the new audio stream formats for the rest of the AUs...
err = AudioUnitSetProperty(mVarispeedUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &asbd, propertySize);
checkErr(err);
err = AudioUnitSetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &asbd, propertySize);
checkErr(err);
//calculate number of buffers from channels
propsize = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) *asbd.mChannelsPerFrame);
//malloc buffer lists
mInputBuffer = (AudioBufferList *)malloc(propsize);
mInputBuffer->mNumberBuffers = asbd.mChannelsPerFrame;
//pre-malloc buffers for AudioBufferLists
for(UInt32 i =0; i< mInputBuffer->mNumberBuffers ; i++) {
mInputBuffer->mBuffers[i].mNumberChannels = 1;
mInputBuffer->mBuffers[i].mDataByteSize = bufferSizeBytes;
mInputBuffer->mBuffers[i].mData = malloc(bufferSizeBytes);
}
//Alloc ring buffer that will hold data between the two audio devices
mBuffer = new CARingBuffer();
mBuffer->Allocate(asbd.mChannelsPerFrame, asbd.mBytesPerFrame, bufferSizeFrames * 20);
return err;
}
void EQEngine::ComputeThruOffset(){
//The initial latency will at least be the saftey offset's of the devices + the buffer sizes
mInToOutSampleOffset = SInt32(mInputDevice.mSafetyOffset + mInputDevice.mBufferSizeFrames +
mOutputDevice.mSafetyOffset + mOutputDevice.mBufferSizeFrames);
}
#pragma mark -
#pragma mark -- IO Procs --
OSStatus EQEngine::InputProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData){
OSStatus err = noErr;
EQEngine *This = (EQEngine *)inRefCon;
if (This->mFirstInputTime < 0.)
This->mFirstInputTime = inTimeStamp->mSampleTime;
//Get the new audio data
err = AudioUnitRender(This->mInputUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames, //# of frames requested
This->mInputBuffer);// Audio Buffer List to hold data
checkErr(err);
if(!err) {
err = This->mBuffer->Store(This->mInputBuffer, Float64(inNumberFrames), SInt64(inTimeStamp->mSampleTime));
}
return err;
}
inline void MakeBufferSilent (AudioBufferList * ioData){
for(UInt32 i=0; i<ioData->mNumberBuffers;i++)
memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);
}
OSStatus EQEngine::OutputProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *TimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData){
OSStatus err = noErr;
EQEngine *This = (EQEngine *)inRefCon;
Float64 rate = 0.0;
AudioTimeStamp inTS, outTS;
if (This->mFirstInputTime < 0.) {
// input hasn't run yet -> silence
MakeBufferSilent (ioData);
return noErr;
}
//use the varispeed playback rate to offset small discrepancies in sample rate
//first find the rate scalars of the input and output devices
err = AudioDeviceGetCurrentTime(This->mInputDevice.mID, &inTS);
// this callback may still be called a few times after the device has been stopped
if (err)
{
MakeBufferSilent (ioData);
return noErr;
}
err = AudioDeviceGetCurrentTime(This->mOutputDevice.mID, &outTS);
checkErr(err);
rate = inTS.mRateScalar / outTS.mRateScalar;
err = AudioUnitSetParameter(This->mVarispeedUnit,kVarispeedParam_PlaybackRate,kAudioUnitScope_Global,0, rate,0);
checkErr(err);
//get Delta between the devices and add it to the offset
if (This->mFirstOutputTime < 0.) {
This->mFirstOutputTime = TimeStamp->mSampleTime;
Float64 delta = (This->mFirstInputTime - This->mFirstOutputTime);
This->ComputeThruOffset();
//changed: 3865519 11/10/04
if (delta < 0.0)
This->mInToOutSampleOffset -= delta;
else
This->mInToOutSampleOffset = -delta + This->mInToOutSampleOffset;
MakeBufferSilent (ioData);
return noErr;
}
//copy the data from the buffers
err = This->mBuffer->Fetch(ioData, inNumberFrames, SInt64(TimeStamp->mSampleTime - This->mInToOutSampleOffset));
checkErr(err);
if(err != kCARingBufferError_OK)
{
MakeBufferSilent (ioData);
SInt64 bufferStartTime, bufferEndTime;
This->mBuffer->GetTimeBounds(bufferStartTime, bufferEndTime);
This->mInToOutSampleOffset = TimeStamp->mSampleTime - bufferStartTime;
}
return noErr;
}

View File

@ -1,13 +0,0 @@
#import "Devices.h"
#import "EQEngine.h"
#import "Utilities.h"
@interface EQHost : NSObject
+(void)createEQEngineWithOutputDevice:(AudioDeviceID)output;
+(void)deleteEQEngine;
+(BOOL)EQEngineExists;
+(void)setEQEngineFrequencyGains:(NSArray*)gains;
+(NSArray*)getEQEngineFrequencyGains;
+(AudioDeviceID)getSelectedOutputDeviceID;
@end

View File

@ -1,96 +0,0 @@
#import <Foundation/Foundation.h>
#import "EQHost.h"
@implementation EQHost
static EQEngine *mEngine;
static AudioDeviceID selectedOutputDeviceID;
static NSNumber *bandMode;
+(void)createEQEngineWithOutputDevice:(AudioDeviceID)output{
BOOL selectedDeviceIsMuted = [Devices getIsMutedForDeviceID: output];
Float32 stashedVolume = [Devices audioDeviceHasVolumeControls:output] ? [Devices getOutputVolumeForDeviceID: output] : 1;
[Devices setOutputVolumeForDeviceID:output to: 0]; //silence the output for now
if([self EQEngineExists]) [self deleteEQEngine];
AudioDeviceID input = [Devices getEQMacDeviceID];
selectedOutputDeviceID = output;
[Devices setOutputVolumeForDeviceID: input to: stashedVolume];
[Devices setDevice: input toMuted: selectedDeviceIsMuted];
[Devices switchToOutputDeviceWithID: input];
[Devices switchToSystemDeviceWithID: input];
mEngine = new EQEngine(input, output);
bandMode = [Storage getSelectedBandMode];
NSArray *frequenciesArray = [Constants getFrequenciesForBandMode: bandMode.stringValue];
UInt32 *frequencies = new UInt32[frequenciesArray.count]();
for (int i = 0; i < frequenciesArray.count; i++) {
frequencies[i] = [[[frequenciesArray objectAtIndex: i] objectForKey:@"frequency"] intValue];
}
mEngine->SetEqFrequencies(frequencies, (UInt32)frequenciesArray.count);
mEngine->Start();
NSArray *savedGains = [Storage getSelectedGains];
[self setEQEngineFrequencyGains: savedGains];
[Devices setOutputVolumeForDeviceID:output to: 1]; //full blast
}
+(void)deleteEQEngine{
if(mEngine){
[Devices setOutputVolumeForDeviceID:[EQHost getSelectedOutputDeviceID] to: 0]; //silence the output for now
mEngine->Stop();
BOOL eqMacDeviceIsMuted = [Devices getIsMutedForDeviceID: [Devices getEQMacDeviceID]];
Float32 volumeToReach = [Devices getOutputVolumeForDeviceID: [Devices getEQMacDeviceID]];
[Devices switchToOutputDeviceWithID:[EQHost getSelectedOutputDeviceID]];
[Devices switchToSystemDeviceWithID: [EQHost getSelectedOutputDeviceID]];
delete mEngine;
mEngine = NULL;
[Devices setOutputVolumeForDeviceID: [self getSelectedOutputDeviceID] to: volumeToReach];
[Devices setDevice: [self getSelectedOutputDeviceID] toMuted: eqMacDeviceIsMuted];
}
}
+(BOOL)EQEngineExists{
return (mEngine != NULL) ? true : false;
}
+(void)setEQEngineFrequencyGains:(NSArray*)gains{
Float32 *array = new Float32[[gains count]];
for(int i = 0; i < [gains count]; i++){
array[i] = [[gains objectAtIndex:i] floatValue];
}
if(mEngine){
mEngine->SetEqGains(array, (UInt32)gains.count);
}
}
+(NSArray*)getEQEngineFrequencyGains{
Float32 *gains = mEngine->GetEqGains();
int nGains = bandMode.intValue;
NSMutableArray *convertedGains = [[NSMutableArray alloc] init];
for(int i = 0; i < nGains; i++){
[convertedGains addObject: mEngine ? [NSNumber numberWithFloat:gains[i]] : @0];
}
return convertedGains;
}
+(AudioDeviceID)getSelectedOutputDeviceID{
if(selectedOutputDeviceID){
return selectedOutputDeviceID;
}
return 0;
}
@end

View File

@ -1,16 +0,0 @@
//
// EQPromotionWindowController.h
// eqMac2
//
// Created by Romans Kisils on 13/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <WebKit/WebView.h>
#import <WebKit/WebFrame.h>
#import "API.h"
#import "EQClickableImageView.h"
#import "Utilities.h"
@interface EQPromotionWindowController : NSWindowController
@end

View File

@ -1,57 +0,0 @@
//
// EQPromotionWindowController.m
// eqMac2
//
// Created by Romans Kisils on 13/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "EQPromotionWindowController.h"
@interface EQPromotionWindowController ()
@property (strong) IBOutlet EQClickableImageView *imageView;
@property (strong) IBOutlet NSButton *button;
@property (strong) NSString *image;
@property (strong) NSString *link;
@end
@implementation EQPromotionWindowController
- (void)windowDidLoad {
[super windowDidLoad];
[_imageView setTarget:self];
[_imageView setClickAction:@selector(openLink)];
[_button setTarget: self];
[API getPromotionWithCallback:^(NSDictionary *resp, NSError * err){
if (resp && !err) {
_image = [resp objectForKey:@"image"];
_link = [resp objectForKey:@"link"];
NSImage *image = [[NSImage alloc] initWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: _image]]];
NSScreen *screen = [NSScreen mainScreen];
NSSize displayPixelSize = [screen frame].size;
CGFloat imageWidth = image.size.width;
CGFloat imageHeight = image.size.height;
CGFloat titleBarHeight = [self getWindowTitlebarHeight];
[self.window setFrame:NSMakeRect(displayPixelSize.width - imageWidth - titleBarHeight, displayPixelSize.height - imageHeight - (titleBarHeight * 3), imageWidth, imageHeight + titleBarHeight) display:YES];
[_imageView setImage:image];
[self.window setLevel:NSScreenSaverWindowLevel + 1];
[self.window orderFront: self];
}
}];
}
-(void)openLink{
if (_link) {
[Utilities openBrowserWithURL: _link];
}
[self.window close];
}
- (CGFloat)getWindowTitlebarHeight{
CGFloat contentHeight = [self.window contentRectForFrameRect: self.window.frame].size.height;
return self.window.frame.size.height - contentHeight;
}
@end

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="EQPromotionWindowController">
<connections>
<outlet property="imageView" destination="oG9-7o-Bwl" id="eqj-Uj-5yO"/>
<outlet property="window" destination="H0l-7m-pOS" id="AYo-RQ-ubV"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="eqMac2 Promotion" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="H0l-7m-pOS" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" utility="YES" HUD="YES"/>
<windowPositionMask key="initialPositionMask" rightStrut="YES" topStrut="YES"/>
<rect key="contentRect" x="2061" y="1085" width="480" height="297"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
<view key="contentView" id="IpE-Qc-FSs">
<rect key="frame" x="0.0" y="0.0" width="480" height="297"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oG9-7o-Bwl" customClass="EQClickableImageView">
<rect key="frame" x="0.0" y="0.0" width="480" height="297"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="kwq-z1-OU3"/>
</imageView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="DOv-5n-Wi8"/>
<outlet property="initialFirstResponder" destination="IpE-Qc-FSs" id="wQf-xl-Tpg"/>
</connections>
<point key="canvasLocation" x="346" y="247.5"/>
</window>
</objects>
</document>

View File

@ -1,19 +0,0 @@
//
// eqMacStatusItemView.h
// eqMac2
//
// Created by Romans Kisils on 13/04/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface eqMacStatusItemView : NSView
@property NSImage* image;
@property NSImage* alternateImage;
@property BOOL clicked;
@property SEL action;
@property SEL rightAction;
@property (nonatomic, weak) id target;
- (void)setHighlightState:(BOOL)state;
@end

View File

@ -1,71 +0,0 @@
//
// eqMacStatusItemView.m
// eqMac2
//
// Created by Romans Kisils on 13/04/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "eqMacStatusItemView.h"
@implementation eqMacStatusItemView
@synthesize image = _image;
@synthesize alternateImage = _alternateImage;
@synthesize clicked = _clicked;
@synthesize action = _action;
@synthesize rightAction = _rightAction;
@synthesize target = _target;
- (void)setHighlightState:(BOOL)state{
if(self.clicked != state){
self.clicked = state;
[self setNeedsDisplay:YES];
}
}
- (void)drawImage:(NSImage *)aImage centeredInRect:(NSRect)aRect{
NSRect imageRect = NSMakeRect((CGFloat)round(aRect.size.width*0.5f-aImage.size.width*0.5f),
(CGFloat)round(aRect.size.height*0.5f-aImage.size.height*0.5f),
aImage.size.width,
aImage.size.height);
[aImage drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}
- (void)drawRect:(NSRect)rect{
if(self.clicked){
[[NSColor selectedMenuItemColor] set];
NSRectFill(rect);
if(self.alternateImage){
[self drawImage:self.alternateImage centeredInRect:rect];
}else if(self.image){
[self drawImage:self.image centeredInRect:rect];
}
}else if(self.image){
[self drawImage:self.image centeredInRect:rect];
}
}
- (void)mouseDown:(NSEvent *)theEvent{
[super mouseDown:theEvent];
[self setHighlightState:!self.clicked];
if ([theEvent modifierFlags] & NSCommandKeyMask){
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}else{
[self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
}
}
- (void)rightMouseDown:(NSEvent *)theEvent{
[super rightMouseDown:theEvent];
[self setHighlightState:!self.clicked];
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}
- (void)dealloc{
self.target = nil;
self.action = nil;
self.rightAction = nil;
}
@end

View File

@ -1,316 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13529"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="EQViewController">
<connections>
<outlet property="balanceSlider" destination="5O3-5r-Qyb" id="Nlx-Md-494"/>
<outlet property="bandFrequencyLabelsView" destination="pfD-yK-NBh" id="LyD-Rs-GVy"/>
<outlet property="bandGainLabelsView" destination="wAd-bO-kX7" id="mj9-v9-vFV"/>
<outlet property="bandLabelsView" destination="pfD-yK-NBh" id="qf4-me-lvi"/>
<outlet property="bandModeButton" destination="A3d-OE-EvB" id="Dnm-OI-B5o"/>
<outlet property="buildLabel" destination="40h-US-vfL" id="ma5-ve-Mrq"/>
<outlet property="deleteButton" destination="j96-Rt-Axz" id="ubn-ze-Qjw"/>
<outlet property="exitButton" destination="DBG-3t-4Br" id="ejU-n2-r36"/>
<outlet property="launchOnStartupCheckbox" destination="u3z-eA-tLq" id="dhM-hD-lqX"/>
<outlet property="leftSpeaker" destination="Tj4-Cd-asv" id="iEC-yW-1Fu"/>
<outlet property="mockSliderView" destination="mxi-4w-muC" id="WXD-dG-tKF"/>
<outlet property="optionsView" destination="zYL-Yc-hBK" id="Tha-hc-CDe"/>
<outlet property="outputPopup" destination="nWT-xx-p7P" id="fe7-54-i4l"/>
<outlet property="presetsPopup" destination="ZNl-vW-MXA" id="mU5-jX-Oew"/>
<outlet property="rightSpeaker" destination="bnt-jk-GQY" id="o0M-Xb-DOb"/>
<outlet property="saveButton" destination="D6P-Fd-jYR" id="eQ3-zA-f8g"/>
<outlet property="settingsView" destination="bsp-60-bff" id="cmK-q8-jkW"/>
<outlet property="showDefaultPresetsCheckbox" destination="q0X-qI-wTp" id="Qmt-sI-PUP"/>
<outlet property="speakerIcon" destination="bYL-Wf-8Na" id="Ntg-bs-2ba"/>
<outlet property="updater" destination="cbi-8I-cSS" id="bN2-GR-j4N"/>
<outlet property="view" destination="l5q-FZ-i9D" id="ASl-08-s8D"/>
<outlet property="volumeBars" destination="zac-4C-CdF" id="Bu0-qg-yOH"/>
<outlet property="volumeSlider" destination="XPj-2L-HZ9" id="TkB-jc-snq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="l5q-FZ-i9D" userLabel="eqView">
<rect key="frame" x="0.0" y="0.0" width="289" height="425"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="673-Qh-f0f">
<rect key="frame" x="3" y="289" width="16" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="▶" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="Kgl-l6-tX3">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="resetEQ:" target="-2" id="9o9-Ds-x6x"/>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j96-Rt-Axz">
<rect key="frame" x="8" y="397" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="deleteDark" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="4Wb-mN-t2v">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="deletePreset:" target="-2" id="lCZ-zC-Ipu"/>
</connections>
</button>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZNl-vW-MXA">
<rect key="frame" x="32" y="393" width="225" height="26"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="center" lineBreakMode="truncatingTail" continuous="YES" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="dDz-cl-VBo" id="otW-zQ-lg9">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="yXO-DJ-zhz">
<items>
<menuItem title="Item 1" state="on" id="dDz-cl-VBo"/>
<menuItem title="Item 2" id="ZCe-TS-9gc"/>
<menuItem title="Item 3" id="ugA-9N-woS"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="changePreset:" target="-2" id="aZc-mS-5Si"/>
</connections>
</popUpButton>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D6P-Fd-jYR">
<rect key="frame" x="262" y="397" width="19" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="saveDark" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="ued-Rm-cUy">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="savePreset:" target="-2" id="fP2-8O-4RG"/>
</connections>
</button>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pfD-yK-NBh">
<rect key="frame" x="17" y="370" width="267" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</customView>
<customView canDrawConcurrently="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mxi-4w-muC">
<rect key="frame" x="17" y="225" width="267" height="145"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</customView>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wAd-bO-kX7">
<rect key="frame" x="17" y="206" width="267" height="15"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</customView>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nWT-xx-p7P">
<rect key="frame" x="6" y="184" width="199" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="center" lineBreakMode="truncatingTail" continuous="YES" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Ccr-c2-Bnc" id="L86-3a-Giu">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="OZa-SA-vIu">
<items>
<menuItem title="Item 1" state="on" id="Ccr-c2-Bnc"/>
<menuItem title="Item 2" id="wYr-Jn-Hi7"/>
<menuItem title="Item 3" id="MOU-fw-XTI"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="changeOutputDevice:" target="-2" id="K30-ST-WIc"/>
</connections>
</popUpButton>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="A3d-OE-EvB">
<rect key="frame" x="206" y="184" width="78" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="31 Bands" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uHT-D8-p1c">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<action selector="toggleBandMode:" target="-2" id="NjF-dN-eaX"/>
</connections>
</button>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2UR-wS-83e" userLabel="VolumeView">
<rect key="frame" x="0.0" y="76" width="289" height="49"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ea0-ri-trG">
<rect key="frame" x="102" y="-1" width="84" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Volume" id="iqy-Uy-lib">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="always" translatesAutoresizingMaskIntoConstraints="NO" id="zac-4C-CdF">
<rect key="frame" x="254" y="20" width="28" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" userInterfaceLayoutDirection="rightToLeft" alignment="left" imageScaling="proportionallyUpOrDown" image="vol4Dark" id="DpF-zh-SV6"/>
</imageView>
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XPj-2L-HZ9">
<rect key="frame" x="30" y="24" width="228" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.5" tickMarkPosition="above" sliderType="linear" id="xrL-0h-vuh"/>
<connections>
<action selector="changeVolume:" target="-2" id="qQ9-Hi-l2g"/>
</connections>
</slider>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bYL-Wf-8Na">
<rect key="frame" x="6" y="20" width="28" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="speakerDark" id="3ZW-YV-tBP"/>
</imageView>
</subviews>
</customView>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="w4j-la-tne" userLabel="BalanceView">
<rect key="frame" x="0.0" y="28" width="289" height="49"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bnt-jk-GQY">
<rect key="frame" x="254" y="20" width="28" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="vol4Dark" id="M4J-gK-3tn"/>
</imageView>
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5O3-5r-Qyb">
<rect key="frame" x="30" y="25" width="229" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" controlSize="small" continuous="YES" alignment="left" minValue="-1" maxValue="1" tickMarkPosition="above" numberOfTickMarks="1" sliderType="linear" id="yzS-cB-IUA"/>
<connections>
<action selector="changeBalance:" target="-2" id="7rF-RJ-I7y"/>
</connections>
</slider>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fAm-Hf-lW2">
<rect key="frame" x="102" y="5" width="84" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Balance" id="uvN-gE-0Zk">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="always" translatesAutoresizingMaskIntoConstraints="NO" id="Tj4-Cd-asv">
<rect key="frame" x="6" y="20" width="28" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" userInterfaceLayoutDirection="rightToLeft" alignment="left" imageScaling="proportionallyDown" image="vol4Dark" id="wiW-xt-uo1"/>
</imageView>
</subviews>
</customView>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zYL-Yc-hBK" userLabel="ButtonsView">
<rect key="frame" x="0.0" y="154" width="289" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="b6m-Ef-QgE">
<rect key="frame" x="6" y="1" width="138" height="28"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="Check for Updates" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="YM7-9y-JzV">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="checkForUpdates:" target="cbi-8I-cSS" id="Ylw-cm-65L"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DNr-NX-E7k">
<rect key="frame" x="146" y="1" width="138" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="Need Help?" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="V1q-qi-UP3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="getHelp:" target="-2" id="9C0-Nv-S1f"/>
</connections>
</button>
</subviews>
</customView>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bsp-60-bff" userLabel="OptionsView">
<rect key="frame" x="0.0" y="125" width="289" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="u3z-eA-tLq">
<rect key="frame" x="140" y="-2" width="144" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Launch on Startup" bezelStyle="regularSquare" imagePosition="right" alignment="right" controlSize="small" inset="2" id="DZ0-E5-rUS">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
<action selector="changeLaunchOnStartup:" target="-2" id="6Sy-M8-sJ6"/>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="q0X-qI-wTp">
<rect key="frame" x="3" y="-3" width="162" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Show Default Presets" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="lrJ-QE-pEL">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
<action selector="switchShowDefaultPresets:" target="-2" id="VuV-Kf-8zd"/>
</connections>
</button>
</subviews>
</customView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DBG-3t-4Br">
<rect key="frame" x="5" y="2" width="44" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="squareTextured" title="Quit" bezelStyle="texturedSquare" alignment="center" continuous="YES" imageScaling="proportionallyDown" inset="2" id="M8W-BG-hUO">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="quitApplication:" target="-2" id="e8g-XX-K0k"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="40h-US-vfL">
<rect key="frame" x="108" y="7" width="73" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Build 2.1" id="bwU-YS-IJK">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dfy-Kg-Qed">
<rect key="frame" x="221" y="2" width="60" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="bevel" title="Uninstall" bezelStyle="rounded" alignment="center" controlSize="small" continuous="YES" imageScaling="proportionallyDown" inset="2" id="EO0-lO-d4i">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="uninstallApplication:" target="-2" id="Uj7-zJ-cPG"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dDB-N0-dD0">
<rect key="frame" x="1" y="375" width="19" height="11"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Hz:" id="2IQ-pN-KC2">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eAf-O6-0hu">
<rect key="frame" x="1" y="211" width="19" height="11"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="dB:" id="38J-7m-xeJ">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<point key="canvasLocation" x="91.5" y="424.5"/>
</customView>
<customObject id="cbi-8I-cSS" customClass="SUUpdater"/>
</objects>
<resources>
<image name="deleteDark" width="20.799968719482422" height="20.799968719482422"/>
<image name="saveDark" width="20.799968719482422" height="20.799968719482422"/>
<image name="speakerDark" width="128" height="128"/>
<image name="vol4Dark" width="67" height="100"/>
</resources>
</document>

View File

@ -1,20 +0,0 @@
//
// EQViewController.h
// eqMac2
//
// Created by Romans Kisils on 10/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "EQHost.h"
#import "SliderGraphView.h"
#import "Constants.h"
#import "AppDelegate.h"
#import "Utilities.h"
#import "Devices.h"
#import "Storage.h"
#import "API.h"
@interface EQViewController : NSViewController <NSComboBoxDelegate>
@end

View File

@ -1,380 +0,0 @@
//
// EQViewController.m
// eqMac2
//
// Created by Romans Kisils on 10/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import "EQViewController.h"
@interface EQViewController ()
@property (strong) IBOutlet NSButton *deleteButton;
@property (strong) IBOutlet NSPopUpButton *presetsPopup;
@property (strong) IBOutlet NSButton *saveButton;
@property (strong) IBOutlet NSView *bandFrequencyLabelsView;
@property (strong) IBOutlet NSView *mockSliderView;
@property (strong) IBOutlet NSView *bandGainLabelsView;
@property (strong) IBOutlet NSPopUpButton *outputPopup;
@property (strong) IBOutlet NSButton *bandModeButton;
@property (strong) IBOutlet NSImageView *speakerIcon;
@property (strong) IBOutlet NSSlider *volumeSlider;
@property (strong) IBOutlet NSImageView *volumeBars;
@property (strong) IBOutlet NSImageView *leftSpeaker;
@property (strong) IBOutlet NSSlider *balanceSlider;
@property (strong) IBOutlet NSImageView *rightSpeaker;
@property (strong) IBOutlet NSView *optionsView;
@property (strong) IBOutlet NSView *settingsView;
@property (strong) IBOutlet NSButton *launchOnStartupCheckbox;
@property (strong) IBOutlet NSButton *showDefaultPresetsCheckbox;
@property (strong) IBOutlet NSTextField *buildLabel;
@end
SliderGraphView *sliderView;
NSNotificationCenter *notify;
NSArray *outputDevices;
NSNumber *bandMode;
CGFloat originalWidth;
CGFloat originalHeight;
@implementation EQViewController
-(void)viewDidLoad {
[super viewDidLoad];
originalWidth = self.view.frame.size.width;
originalHeight = self.view.frame.size.height;
sliderView = [[SliderGraphView alloc] initWithFrame: _mockSliderView.frame];
[sliderView setAutoresizingMask: _mockSliderView.autoresizingMask];
_mockSliderView = nil;
[self.view addSubview:sliderView];
[_presetsPopup setTitle:@""];
[_outputPopup setTitle:@""];
notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self selector:@selector(sliderGraphChanged) name:@"sliderGraphChanged" object:nil];
[notify addObserver:self selector:@selector(populateOutputPopup) name:@"devicesChanged" object:nil];
[notify addObserver:self selector:@selector(readjustView) name:@"popoverWillOpen" object:nil];
[_buildLabel setStringValue:[@"Build " stringByAppendingString:[Utilities getAppVersion]]];
bandMode = [Storage getSelectedBandMode];
[_showDefaultPresetsCheckbox setState: [Storage getShowDefaultPresets] ? NSOnState : NSOffState];
[self setBandModeSettings];
[self readjustView];
[self populatePresetPopup];
[self populateOutputPopup];
[self readjustVolumeControls];
[Utilities executeBlock: ^{
if ([self.view.window isVisible]) {
[self readjustVolumeControls];
}
} every: .5];
}
-(void)viewDidAppear{
[sliderView forceRedraw];
[self populateOutputPopup];
[_deleteButton setImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"deleteLight.png"] : [NSImage imageNamed:@"deleteDark.png"]];
[_saveButton setImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"saveLight.png"] : [NSImage imageNamed:@"saveDark.png"]];
[_speakerIcon setImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"speakerLight.png"] : [NSImage imageNamed:@"speakerDark.png"]];
[_launchOnStartupCheckbox setState: [Utilities launchOnLogin] ? NSOnState : NSOffState];
[Utilities executeBlock:^{
[self setState];
} after:.1];
}
-(void)setBandFrequencyLabels{
NSArray *sliderPositions = [sliderView getSliderXPosition];
[_bandFrequencyLabelsView setSubviews: [[NSArray alloc] init]];
NSArray *frequencies = [Constants getFrequenciesForBandMode: [bandMode stringValue]];
CGFloat labelWidth = 38;
CGFloat labelHeight = 17;
CGFloat labelYPos = _bandFrequencyLabelsView.bounds.size.height / 2 - labelHeight / 2;
int index = -1;
for(NSNumber *position in sliderPositions) {
index++;
CGFloat labelXPos = [position floatValue] - labelWidth / 2;
NSTextField *label = [[NSTextField alloc] initWithFrame: NSMakeRect(labelXPos, labelYPos, labelWidth, labelHeight)];
[label setBackgroundColor: [NSColor colorWithRed:0 green:0 blue:0 alpha:0]];
[label setBordered:NO];
[label setStringValue: [[frequencies objectAtIndex: index] objectForKey:@"label"]];
[label setAlignment: NSCenterTextAlignment];
CGFloat fontSize = bandMode.intValue == 10 ? 9 : 7;
[label setFont: [NSFont systemFontOfSize: fontSize]];
[label setEditable:NO];
[_bandFrequencyLabelsView addSubview:label];
}
}
-(void)setBandGainLabels{
NSArray *sliderPositions = [sliderView getSliderXPosition];
[_bandGainLabelsView setSubviews: [[NSArray alloc] init]];
NSArray *gains = [EQHost getEQEngineFrequencyGains];
CGFloat labelWidth = 38;
CGFloat labelHeight = 17;
CGFloat labelYPos = _bandFrequencyLabelsView.bounds.size.height / 2 - labelHeight / 2;
int index = -1;
for(NSNumber *position in sliderPositions) {
index++;
CGFloat labelXPos = [position floatValue] - labelWidth / 2;
NSTextField *label = [[NSTextField alloc] initWithFrame: NSMakeRect(labelXPos, labelYPos, labelWidth, labelHeight)];
[label setBackgroundColor: [NSColor colorWithRed:0 green:0 blue:0 alpha:0]];
[label setBordered:NO];
CGFloat gain = round([Utilities mapValue:[[gains objectAtIndex: index] floatValue] withInMin:-1 InMax:1 OutMin:-24 OutMax:24]);
[label setStringValue: [NSString stringWithFormat:@"%@%.0f", gain > 0 ? @"+": @"", gain]];
[label setAlignment: NSCenterTextAlignment];
[label setEditable:NO];
CGFloat fontSize = bandMode.intValue == 10 ? 9 : 7;
[label setFont: [NSFont systemFontOfSize: fontSize]];
[_bandGainLabelsView addSubview:label];
}
}
-(void)populatePresetPopup{
[_presetsPopup removeAllItems];
NSArray *presets = [Storage getPresetsNames];
[_presetsPopup addItemsWithTitles: [Utilities orderedStringArrayFromStringArray: presets]];
[_presetsPopup setTitle: [Storage getSelectedPresetName]];
}
- (IBAction)changePreset:(NSPopUpButton *)sender {
NSString *presetName = [_presetsPopup title];
[Storage setSelectedPresetName: presetName];
NSArray *gains = [Storage getGainsForPresetName: presetName];
[Storage setSelectedGains: gains];
[sliderView animateBandsToValues:gains];
[EQHost setEQEngineFrequencyGains:gains];
[self setBandGainLabels];
}
- (IBAction)deletePreset:(id)sender {
if(![[_presetsPopup title] isEqualToString:@"Flat"]){
[Storage deletePresetWithName:[_presetsPopup title]];
[self populatePresetPopup];
[self resetEQ:nil];
}
}
- (IBAction)savePreset:(NSButton *)sender {
NSString *newPresetName = [Utilities showAlertWithInputAndTitle:@"Please enter a name for your new preset."];
if(![newPresetName isEqualToString:@""]){
[Storage savePresetWithName:newPresetName andGains:[sliderView getBandValues]];
[Storage setSelectedPresetName: newPresetName];
[self populatePresetPopup];
[_presetsPopup selectItemWithTitle:newPresetName];
}
}
-(void)setState{
NSLog(@"setState");
[_presetsPopup setTitle: [Storage getSelectedPresetName]];
NSArray *selectedGains = [Storage getSelectedGains];
[EQHost setEQEngineFrequencyGains: selectedGains];
[sliderView animateBandsToValues: selectedGains];
[Utilities executeBlock:^{ [self setBandGainLabels];} after:.1];
}
-(void)sliderGraphChanged{
NSString *popupTitle = @"Custom";
[_presetsPopup setTitle: popupTitle];
[Storage setSelectedPresetName: popupTitle];
NSArray *selectedGains = [sliderView getBandValues];
[Storage setSelectedGains: selectedGains];
[Storage setSelectedCustomGains: selectedGains];
[EQHost setEQEngineFrequencyGains: selectedGains];
[self setBandGainLabels];
}
- (IBAction)resetEQ:(id)sender {
NSString *presetName = @"Flat";
[_presetsPopup setTitle: presetName];
[Storage setSelectedPresetName: presetName];
NSMutableArray *flatGains = [@[] mutableCopy];
for (int i = 0; i < [bandMode intValue]; i++) [flatGains addObject:@0];
[Storage setSelectedGains: flatGains];
[sliderView animateBandsToValues:flatGains];
[EQHost setEQEngineFrequencyGains:flatGains];
[self setBandGainLabels];
}
-(void)populateOutputPopup{
[_outputPopup removeAllItems];
outputDevices = [Devices getAllUsableDevices];
NSMutableArray *outputDeviceNames = [[NSMutableArray alloc] init];
for (NSDictionary *device in outputDevices) {
[outputDeviceNames addObject: [device objectForKey:@"name"]];
}
[_outputPopup addItemsWithTitles: [Utilities orderedStringArrayFromStringArray: outputDeviceNames]];
AudioDeviceID selectedDeviceID = [EQHost EQEngineExists] ? [EQHost getSelectedOutputDeviceID] : [Devices getCurrentDeviceID];
NSString *nameOfSelectedDevice = [Devices getDeviceNameByID: selectedDeviceID];
[_outputPopup selectItemWithTitle: nameOfSelectedDevice];
}
- (IBAction)changeOutputDevice:(id)sender {
AudioDeviceID selectedOutputDevice = [EQHost getSelectedOutputDeviceID];
for (NSDictionary *device in outputDevices) {
if ([[device objectForKey:@"name"] isEqualToString: [_outputPopup titleOfSelectedItem]]) {
selectedOutputDevice = [[device objectForKey:@"id"] intValue];
}
}
[Devices setOutputVolumeForDeviceID: selectedOutputDevice to: [Devices getOutputVolumeForDeviceID:[Devices getEQMacDeviceID]]];
[Devices switchToOutputDeviceWithID: selectedOutputDevice];
}
- (IBAction)toggleBandMode:(id)sender {
[sender setEnabled: NO];
bandMode = [bandMode intValue] == 10 ? @31 : @10;
[Storage setSelectedBandMode: bandMode];
[self populatePresetPopup];
[self readjustView];
[self setBandModeSettings];
[Utilities executeBlock:^{
[EQHost deleteEQEngine];
[self setState];
[sender setEnabled: YES];
} after: 0.1];
}
-(void)setBandModeSettings{
[sliderView setNSliders: [bandMode intValue]];
[_showDefaultPresetsCheckbox setEnabled: [bandMode intValue] == 10];
}
-(void)readjustView{
[Utilities executeBlock:^{
[self setBandFrequencyLabels];
} after:0.01];
[_bandModeButton setTitle: [[bandMode intValue] == 10 ? @"31" : @"10" stringByAppendingString:@" Bands"]];
CGFloat width = [bandMode intValue] == 10 ? originalWidth : originalWidth * 2;
CGFloat height = [bandMode intValue] == 10 ? originalHeight : 338;
[self.view setFrame: NSMakeRect(self.view.frame.origin.x, self.view.frame.origin.y, width, height)];
[notify postNotificationName:@"readjustPopover" object:nil];
}
-(void)readjustVolumeControls{
//VOLUME
Float32 currentVolume = [Devices getOutputVolumeForDeviceID:[Devices getVolumeControllerDeviceID]];
[_volumeSlider setFloatValue:currentVolume];
[self changeVolumeIcons:currentVolume];
//BALANCE
Float32 currentBalance = [Devices getInputBalanceForDeviceID:[Devices getEQMacDeviceID]];
[_balanceSlider setFloatValue:currentBalance];
[self changeBalanceIcons:currentBalance];
}
- (IBAction)changeVolume:(id)sender {
Float32 volume = [sender floatValue];
[Devices setOutputVolumeForDeviceID:[Devices getVolumeControllerDeviceID] to:volume];
[self changeVolumeIcons:volume];
}
-(void)changeVolumeIcons:(CGFloat)volume{
[_volumeBars setHidden:NO];
if (volume == 0) {
[_volumeBars setHidden:YES];
}else if(volume >= QUARTER_VOLUME_STEP && volume <= 0.25){
[_volumeBars setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol1Light.png"] : [NSImage imageNamed:@"vol1Dark.png"]];
}else if(volume >0.25 && volume <= 0.5){
[_volumeBars setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol2Light.png"] : [NSImage imageNamed:@"vol2Dark.png"]];
}else if(volume >0.5 && volume <= 0.75){
[_volumeBars setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol3Light.png"] : [NSImage imageNamed:@"vol3Dark.png"]];
}else if(volume >0.75 && volume <= 1){
[_volumeBars setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]];
}
}
- (IBAction)changeBalance:(NSSlider *)sender {
Float32 balance = [sender floatValue];
[Devices setInputBalanceForDeviceID: [Devices getEQMacDeviceID] to:balance];
[self changeBalanceIcons: [sender floatValue]];
}
-(void)changeBalanceIcons:(CGFloat)balance{
if (balance == -1) {
[_leftSpeaker setImage: [Utilities flipImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol1Light.png"] : [NSImage imageNamed:@"vol1Dark.png"]];
}else if(balance >-1 && balance <= -0.5){
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol2Light.png"] : [NSImage imageNamed:@"vol2Dark.png"]];
}else if(balance > -0.5 && balance < 0){
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol3Light.png"] : [NSImage imageNamed:@"vol3Dark.png"]];
}else if(balance == 0){
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]];
}else if(balance >0 && balance <= 0.5){
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol3Light.png"] : [NSImage imageNamed:@"vol3Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]];
}else if(balance >0.5 && balance < 1){
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol2Light.png"] : [NSImage imageNamed:@"vol2Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]];
}else{
[_leftSpeaker setImage: [Utilities flipImage:[Utilities isDarkMode] ? [NSImage imageNamed:@"vol1Light.png"] : [NSImage imageNamed:@"vol1Dark.png"]]];
[_rightSpeaker setImage: [Utilities isDarkMode] ? [NSImage imageNamed:@"vol4Light.png"] : [NSImage imageNamed:@"vol4Dark.png"]];
}
}
- (IBAction)supportProject:(id)sender {
[Utilities openBrowserWithURL:SUPPORT_URL];
}
- (IBAction)getHelp:(id)sender {
[Utilities openBrowserWithURL:HELP_URL];
}
- (IBAction)changeLaunchOnStartup:(NSButton*)sender {
[Utilities setLaunchOnLogin:[sender state] == NSOnState ? true : false];
}
- (IBAction)switchShowDefaultPresets:(NSButton *)sender {
[Storage setShowDefaultPresets: [sender state] == NSOnState];
[self populatePresetPopup];
}
- (IBAction)quitApplication:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:@"closeApp" object:nil];
}
- (IBAction)uninstallApplication:(id)sender {
if([Utilities showAlertWithTitle:@"Uninstall eqMac2?"
andMessage:@"Are you sure about this?"
andButtons:@[@"Yes, uninstall",@"No, cancel"]] == NSAlertFirstButtonReturn){
if([Utilities runShellScriptWithName:@"uninstall_driver"]){
if([EQHost EQEngineExists]) [EQHost deleteEQEngine];
[Utilities setLaunchOnLogin: NO];
NSString *helperBundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/Resources/eqMac2Helper.app"];
[Utilities setLaunchOnLogin:NO forBundlePath: helperBundlePath];
[[NSFileManager defaultManager] removeItemAtPath:[[NSBundle mainBundle] bundlePath] error:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"closeApp" object:nil];
}
}
}
@end

View File

@ -1,60 +0,0 @@
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "Ccr-c2-Bnc"; */
"Ccr-c2-Bnc.title" = "Item 1";
/* Class = "NSButtonCell"; title = "Launch on Startup"; ObjectID = "DZ0-E5-rUS"; */
"DZ0-E5-rUS.title" = "Launch on Startup";
/* Class = "NSButtonCell"; title = "Uninstall"; ObjectID = "EO0-lO-d4i"; */
"EO0-lO-d4i.title" = "Uninstall";
/* Class = "NSButtonCell"; title = "▶"; ObjectID = "Kgl-l6-tX3"; */
"Kgl-l6-tX3.title" = "▶";
/* Class = "NSButtonCell"; title = "Quit"; ObjectID = "M8W-BG-hUO"; */
"M8W-BG-hUO.title" = "Quit";
/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "MOU-fw-XTI"; */
"MOU-fw-XTI.title" = "Item 3";
/* Class = "NSTextFieldCell"; title = "It took 1000+ hours to develop eqMac"; ObjectID = "P8v-Sl-g0g"; */
"P8v-Sl-g0g.title" = "It took 1000+ hours to develop eqMac";
/* Class = "NSButtonCell"; title = "Need Help?"; ObjectID = "V1q-qi-UP3"; */
"V1q-qi-UP3.title" = "Need Help?";
/* Class = "NSButtonCell"; title = "Report a Bug"; ObjectID = "XxV-RG-uvk"; */
"XxV-RG-uvk.title" = "Report a Bug";
/* Class = "NSButtonCell"; title = "Check for Updates"; ObjectID = "YM7-9y-JzV"; */
"YM7-9y-JzV.title" = "Check for Updates";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "ZCe-TS-9gc"; */
"ZCe-TS-9gc.title" = "Item 2";
/* Class = "NSTextFieldCell"; title = "Build 2.1"; ObjectID = "bwU-YS-IJK"; */
"bwU-YS-IJK.title" = "Build 2.1";
/* Class = "NSButtonCell"; title = "Support eqMac"; ObjectID = "ckU-q9-bDF"; */
"ckU-q9-bDF.title" = "Support eqMac";
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "dDz-cl-VBo"; */
"dDz-cl-VBo.title" = "Item 1";
/* Class = "NSTextFieldCell"; title = "Volume"; ObjectID = "iqy-Uy-lib"; */
"iqy-Uy-lib.title" = "Volume";
/* Class = "NSButtonCell"; title = "Show Default Presets"; ObjectID = "lrJ-QE-pEL"; */
"lrJ-QE-pEL.title" = "Show Default Presets";
/* Class = "NSButtonCell"; title = "31 Bands"; ObjectID = "uHT-D8-p1c"; */
"uHT-D8-p1c.title" = "31 Bands";
/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "ugA-9N-woS"; */
"ugA-9N-woS.title" = "Item 3";
/* Class = "NSTextFieldCell"; title = "Balance"; ObjectID = "uvN-gE-0Zk"; */
"uvN-gE-0Zk.title" = "Balance";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "wYr-Jn-Hi7"; */
"wYr-Jn-Hi7.title" = "Item 2";

View File

@ -1,60 +0,0 @@
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "Ccr-c2-Bnc"; */
"Ccr-c2-Bnc.title" = "Item 1";
/* Class = "NSButtonCell"; title = "Launch on Startup"; ObjectID = "DZ0-E5-rUS"; */
"DZ0-E5-rUS.title" = "Запуск при старте";
/* Class = "NSButtonCell"; title = "Uninstall"; ObjectID = "EO0-lO-d4i"; */
"EO0-lO-d4i.title" = "Удалить";
/* Class = "NSButtonCell"; title = "▶"; ObjectID = "Kgl-l6-tX3"; */
"Kgl-l6-tX3.title" = "▶";
/* Class = "NSButtonCell"; title = "Quit"; ObjectID = "M8W-BG-hUO"; */
"M8W-BG-hUO.title" = "Выйти";
/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "MOU-fw-XTI"; */
"MOU-fw-XTI.title" = "Item 3";
/* Class = "NSTextFieldCell"; title = "It took 1000+ hours to develop eqMac"; ObjectID = "P8v-Sl-g0g"; */
"P8v-Sl-g0g.title" = "На разработку eqMac2 ушло 1000+ часов";
/* Class = "NSButtonCell"; title = "Need Help?"; ObjectID = "V1q-qi-UP3"; */
"V1q-qi-UP3.title" = "Нужна помощь?";
/* Class = "NSButtonCell"; title = "Report a Bug"; ObjectID = "XxV-RG-uvk"; */
"XxV-RG-uvk.title" = "Нашли ошибку?";
/* Class = "NSButtonCell"; title = "Check for Updates"; ObjectID = "YM7-9y-JzV"; */
"YM7-9y-JzV.title" = "Обновить";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "ZCe-TS-9gc"; */
"ZCe-TS-9gc.title" = "Item 2";
/* Class = "NSTextFieldCell"; title = "Build 2.1"; ObjectID = "bwU-YS-IJK"; */
"bwU-YS-IJK.title" = "Сборка 2.1";
/* Class = "NSButtonCell"; title = "Support eqMac"; ObjectID = "ckU-q9-bDF"; */
"ckU-q9-bDF.title" = "Поддержать eqMac";
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "dDz-cl-VBo"; */
"dDz-cl-VBo.title" = "Item 1";
/* Class = "NSTextFieldCell"; title = "Volume"; ObjectID = "iqy-Uy-lib"; */
"iqy-Uy-lib.title" = "Громкость";
/* Class = "NSButtonCell"; title = "Show Default Presets"; ObjectID = "lrJ-QE-pEL"; */
"lrJ-QE-pEL.title" = "Показ. стандартные Пресеты";
/* Class = "NSButtonCell"; title = "31 Bands"; ObjectID = "uHT-D8-p1c"; */
"uHT-D8-p1c.title" = "31 Полос";
/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "ugA-9N-woS"; */
"ugA-9N-woS.title" = "Item 3";
/* Class = "NSTextFieldCell"; title = "Balance"; ObjectID = "uvN-gE-0Zk"; */
"uvN-gE-0Zk.title" = "Баланс";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "wYr-Jn-Hi7"; */
"wYr-Jn-Hi7.title" = "Item 2";

View File

@ -1,16 +0,0 @@
//
// Logger.h
// eqMac2
//
// Created by Romans Kisils on 05/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Constants.h"
#import "Utilities.h"
@interface Logger : NSObject
+(void)log:(id)anything;
+(void)error:(id)anything;
@end

View File

@ -1,23 +0,0 @@
//
// Logger.m
// eqMac2
//
// Created by Romans Kisils on 05/11/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "Logger.h"
@implementation Logger
+(void)log:(id)anything{
if (LOG) [self logOnLevel:@"log" andAnything: anything];
}
+(void)error:(id)anything{
if (LOG) [self logOnLevel:@"error" andAnything: anything];
}
+(void)logOnLevel:(NSString*)level andAnything:(id)anything{
NSLog(@"Logger.%@: %@", level, anything);
}
@end

View File

@ -1,17 +0,0 @@
//
// NSAppEventCatcher.h
// eqMac
//
// Created by Romans Kisils on 30/01/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface NSAppEventCatcher : NSApplication
typedef enum {
UP,
MUTE,
DOWN
} VOLUME_CHANGE_KEY;
@end

View File

@ -1,22 +0,0 @@
//
// NSAppEventCatcher.m
// eqMac
//
// Created by Romans Kisils on 30/01/2017.
// Copyright © 2017 bitgapp. All rights reserved.
//
#import "NSAppEventCatcher.h"
@implementation NSAppEventCatcher
- (void)sendEvent: (NSEvent*)event{
if([event type] == NSKeyDown && [event keyCode] == 53){
[[NSNotificationCenter defaultCenter] postNotificationName:@"escapePressed" object:nil];
}
[super sendEvent: event];
}
@end

View File

@ -1,23 +0,0 @@
#!/bin/sh
# enable install of apps downloaded from anywhere
spctl --master-disable
# remove eqMac 1.0 driver
kextunload /System/Library/Extensions/eqMacDriver.kext/
rm -rf /System/Library/Extensions/eqMacDriver.kext/
# remove eqMac < 2.1 driver
kextunload /System/Library/Extensions/eqMac2Driver.kext/
rm -rf /System/Library/Extensions/eqMac2Driver.kext/
touch /System/Library/Extensions
# get current directory path
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# install the new driver
cp -R $DIR/eqMac2Driver.kext /System/Library/Extensions/
kextload -tv /System/Library/Extensions/eqMac2Driver.kext
touch /System/Library/Extensions

View File

@ -1,7 +0,0 @@
#!/bin/sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
kextunload /System/Library/Extensions/eqMac2Driver.kext/
rm -rf /System/Library/Extensions/eqMac2Driver.kext/
touch /System/Library/Extensions

View File

@ -1,20 +0,0 @@
//
// SliderGraphView.h
// eqMac2
//
// Created by Roman on 06/03/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
#import "Utilities.h"
@interface SliderGraphView : NSView
-(void)animateBandsToValues:(NSArray*)values;
-(NSArray*)getBandValues;
-(NSArray*)getSliderXPosition;
-(void)setNSliders:(int)number;
-(void)forceRedraw;
@end

View File

@ -1,326 +0,0 @@
//
// SliderGraphView.m
// eqMac2
//
// Created by Roman on 06/03/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import "SliderGraphView.h"
CGFloat knobSize;
CGFloat sliderBarWidth;
UInt nSliders;
bool dragging;
int sliderSelected;
NSMutableArray *topBars;
NSMutableArray *bottomBars;
NSTimer *knobAnimationTimer;
NSBezierPath *selectedKnob;
NSMutableArray *knobArray;
NSMutableArray *sliderBarArray;
NSColor *drawingColor;
NSBezierPath *graph;
NSBezierPath *middleLine;
NSMutableArray *bandValues;
CGFloat padding;
@implementation SliderGraphView
#pragma mark Initialization
-(id)initWithFrame:(NSRect)frameRect{
self = [super initWithFrame:frameRect];
if(self){
nSliders = 10;
knobSize = 10;
sliderBarWidth = 3;
padding = 5;
dragging = false;
}
return self;
}
-(void)generateAssets{
knobArray = [[NSMutableArray alloc] init];
sliderBarArray = [[NSMutableArray alloc] init];
CGFloat x = padding;
CGFloat y = self.bounds.size.height/2 - knobSize/2;
CGFloat gap = (self.bounds.size.width - knobSize * nSliders - padding * 2) / (nSliders - 1) + knobSize;
for(int i = 0; i < nSliders; i++){
NSBezierPath *knob = [NSBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, knobSize, knobSize)];
[knobArray addObject:knob];
[sliderBarArray addObject:[NSBezierPath bezierPathWithRect:CGRectMake(x + knobSize/2 - sliderBarWidth/2, 0, sliderBarWidth, self.bounds.size.height)]];
x+=gap;
}
middleLine = [NSBezierPath bezierPathWithRect:CGRectMake([[sliderBarArray firstObject] bounds].origin.x, self.bounds.size.height/2 - sliderBarWidth/4, [[sliderBarArray lastObject] bounds].origin.x - [[sliderBarArray firstObject] bounds].origin.x, sliderBarWidth/2)];
topBars = [[NSMutableArray alloc] init];
bottomBars = [[NSMutableArray alloc] init];
NSImage *propImage = [NSImage imageNamed:@"blueLine.png"];
for (int i = 0; i <= self.bounds.size.height/2/propImage.size.height; i++) {
NSImage *topBar = [NSImage imageNamed:@"blueLine.png"];
NSImage *bottomBar = [NSImage imageNamed:@"redLine.png"];
[topBar setSize:CGSizeMake([[sliderBarArray lastObject] bounds].origin.x - [[sliderBarArray firstObject] bounds].origin.x, topBar.size.height)];
[bottomBar setSize:CGSizeMake([[sliderBarArray lastObject] bounds].origin.x - [[sliderBarArray firstObject] bounds].origin.x, bottomBar.size.height)];
[topBars addObject:topBar];
[bottomBars addObject:bottomBar];
}
[self newGraphFromKnobs];
}
#pragma mark Drawing
-(void)drawRect:(NSRect)dirtyRect {
if(!knobArray || !sliderBarArray) [self generateAssets];
[super drawRect:dirtyRect];
[graph addClip];
int count = 0;
for(NSImage *bar in topBars){
[bar drawAtPoint:CGPointMake([[sliderBarArray firstObject] bounds].origin.x, (self.bounds.size.height/2 + (count * bar.size.height))) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction: 1 - (count*.1)];
count++;
}
count = 0;
for(NSImage *bar in bottomBars){
[bar drawAtPoint:CGPointMake([[sliderBarArray firstObject] bounds].origin.x, (self.bounds.size.height/2 - ((count + 1) * bar.size.height))) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction: 1 - (count*.1)];
count++;
}
[NSGraphicsContext restoreGraphicsState];
drawingColor = [Utilities isDarkMode] ? [NSColor whiteColor] : [NSColor blackColor];
[drawingColor set];
[graph setLineWidth:sliderBarWidth];
[graph stroke];
drawingColor = [Utilities isDarkMode] ? [NSColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1] : [NSColor colorWithRed:0.15 green:0.15 blue:0.15 alpha:1];
[drawingColor set];
for(NSBezierPath *bar in sliderBarArray){
[bar fill];
}
[middleLine fill];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
for(NSBezierPath *knob in knobArray){
drawingColor = [Utilities isDarkMode] ? [NSColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1] : [NSColor colorWithRed:0.15 green:0.15 blue:0.15 alpha:1];
[drawingColor set];
[knob fill];
drawingColor = [Utilities isDarkMode] ? [NSColor colorWithRed:0.15 green:0.15 blue:0.15 alpha:1] : [NSColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1];
[drawingColor set];
[knob stroke];
[tempArray addObject:[NSNumber numberWithFloat:[self mapValue:knob.bounds.origin.y inMin:0 inMax:self.bounds.size.height-knobSize outMin:-1 outMax:1]]];
}
bandValues = tempArray;
}
#pragma mark Mouse events
-(void)mouseDragged:(NSEvent*)e{
CGPoint point = [self convertPoint:[e locationInWindow] fromView:nil];
if(dragging){
if(point.y > self.bounds.size.height - knobSize/2 || point.y < knobSize/2) return;
NSAffineTransform *transform = [NSAffineTransform transform];
NSBezierPath *selectedKnob = [knobArray objectAtIndex:sliderSelected];
CGPoint knobPos = [selectedKnob bounds].origin;
CGFloat knobPosY = knobPos.y + knobSize/2;
CGFloat halfHeight = self.bounds.size.height / 2;
CGFloat diffFromKnobToPoint = point.y - knobPosY;
CGFloat distFromKnobToPoint = diffFromKnobToPoint >=0 ? diffFromKnobToPoint : -diffFromKnobToPoint;
CGFloat diffFromKnobToMiddle = halfHeight - knobPosY;
CGFloat distFromKnobToMiddle = diffFromKnobToMiddle >= 0 ? diffFromKnobToMiddle : -diffFromKnobToMiddle;
BOOL dirUp = diffFromKnobToPoint > 0;
CGFloat yTransform = diffFromKnobToPoint;
if(distFromKnobToMiddle < 3){
if((dirUp && diffFromKnobToMiddle > 0) || (!dirUp && diffFromKnobToMiddle < 0)){
yTransform = diffFromKnobToMiddle;
[[NSHapticFeedbackManager defaultPerformer] performFeedbackPattern:NSHapticFeedbackPatternAlignment performanceTime:NSHapticFeedbackPerformanceTimeDefault];
}
}
if(round(knobPosY) == round(halfHeight) && distFromKnobToPoint < 7){
yTransform = 0;
}
[transform translateXBy: 0 yBy: yTransform];
[[knobArray objectAtIndex:sliderSelected] transformUsingAffineTransform: transform];
[self newGraphFromKnobs];
[self postNotification];
return;
}else{
sliderSelected = 0;
for(NSBezierPath *knob in knobArray){
if([knob containsPoint:point]){
dragging = true;
[self transformKnob:knob toPoint:point withAdjustment:YES];
[self newGraphFromKnobs];
[self postNotification];
return;
}else{
sliderSelected++;
}
}
}
[self postNotification];
}
-(void)mouseDown:(NSEvent *)e{
CGPoint point = [self convertPoint:[e locationInWindow] fromView:nil];
for(NSBezierPath *knob in knobArray){
if([knob containsPoint:CGPointMake(point.x, knob.bounds.origin.y + knobSize/2)]){
[self transformKnob:knob toPoint:point withAdjustment:YES];
[self newGraphFromKnobs];
[self postNotification];
return;
}
}
}
-(void)postNotification{
[[NSNotificationCenter defaultCenter] postNotificationName:@"sliderGraphChanged" object:self];
}
-(void)mouseUp:(NSEvent *)e{
if(dragging){
dragging = false;
sliderSelected = 0;
}
[self postNotification];
}
#pragma mark External methods
-(void)animateBandsToValues:(NSArray*)values{
if([values count] != nSliders){
return;
}
NSMutableArray *steps = [[NSMutableArray alloc] init];
for(int s = 0; s < nSliders; s++){
CGFloat yPointToReach = [self mapValue:[[values objectAtIndex:s] floatValue] inMin:-1 inMax:1 outMin:0 outMax: self.bounds.size.height - knobSize];
CGFloat diff = yPointToReach - [[knobArray objectAtIndex:s] bounds].origin.y;
CGFloat step = diff/30;
[steps addObject:[NSNumber numberWithFloat:step]];
}
[self animateFrameWithSteps:steps andFrame:0];
}
-(void)animateFrameWithSteps:(NSArray*)steps andFrame:(int)frame{
int k = 0;
for(NSBezierPath* knob in knobArray){
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy: 0 yBy: [[steps objectAtIndex:k] floatValue]];
[knob transformUsingAffineTransform: transform];
k++;
}
[self newGraphFromKnobs];
frame++;
if(frame < 30){
CGFloat delayInSeconds = frame*0.001;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self animateFrameWithSteps:steps andFrame:frame];
});
}else{
return;
}
}
#pragma mark Helpers
-(void)transformKnob:(NSBezierPath*)knob toPoint:(CGPoint)point withAdjustment:(BOOL)withAdjustment{
if(point.y > self.bounds.size.height - knobSize/2 || point.y < knobSize/2) return;
CGPoint knobPos = knob.bounds.origin;
NSAffineTransform *transform = [NSAffineTransform transform];
CGFloat adjustment = knobPos.y;
if(withAdjustment){
adjustment += knobSize/2;
}
[transform translateXBy: 0 yBy: point.y - adjustment];
[knob transformUsingAffineTransform: transform];
}
-(void)newGraphFromKnobs{
NSMutableArray *points = [[NSMutableArray alloc] init];
for(NSBezierPath *knob in knobArray){
NSValue *value = [NSValue valueWithPoint:CGPointMake(knob.bounds.origin.x + knobSize/2, knob.bounds.origin.y + knobSize/2)];
[points addObject: value];
}
graph = [self generateBezierPathFromPoints:points];
[self setNeedsDisplay:YES];
}
-(CGFloat)mapValue:(CGFloat)x inMin:(CGFloat)in_min inMax:(CGFloat)in_max outMin:(CGFloat)out_min outMax:(CGFloat) out_max{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
- (NSBezierPath*)generateBezierPathFromPoints:(NSMutableArray *)points{
NSBezierPath *path = [NSBezierPath bezierPath];
float granularity = 100;
[points insertObject:[NSValue valueWithPoint:CGPointMake([[points firstObject] pointValue].x, self.bounds.size.height/2)] atIndex:0];
[points addObject:[NSValue valueWithPoint:CGPointMake([[points lastObject] pointValue].x, self.bounds.size.height/2)]];
[path moveToPoint:[[points firstObject] pointValue]];
for (int index = 1; index < points.count - 2 ; index++) {
CGPoint point0 = [[points objectAtIndex:index - 1] pointValue];
CGPoint point1 = [[points objectAtIndex:index] pointValue];
CGPoint point2 = [[points objectAtIndex:index + 1] pointValue];
CGPoint point3 = [[points objectAtIndex:index + 2] pointValue];
for (int i = 1; i < granularity ; i++) {
float t = (float) i * (1.0f / (float) granularity);
float tt = t * t;
float ttt = tt * t;
CGPoint pi;
pi.x = 0.5 * (2*point1.x+(point2.x-point0.x)*t + (2*point0.x-5*point1.x+4*point2.x-point3.x)*tt + (3*point1.x-point0.x-3*point2.x+point3.x)*ttt);
pi.y = 0.5 * (2*point1.y+(point2.y-point0.y)*t + (2*point0.y-5*point1.y+4*point2.y-point3.y)*tt + (3*point1.y-point0.y-3*point2.y+point3.y)*ttt);
if (pi.x > point0.x) {
[path lineToPoint:pi];
}
}
[path lineToPoint:point2];
}
[path lineToPoint:[[points objectAtIndex:[points count] - 1] pointValue]];
return path;
}
-(NSArray*)getBandValues{
return bandValues;
}
-(NSArray*)getSliderXPosition{
NSMutableArray *positions = [[NSMutableArray alloc] init];
for (NSBezierPath *knob in knobArray) {
[positions addObject: [NSNumber numberWithFloat: knob.bounds.origin.x + knobSize / 2]];
}
return positions;
}
-(void)setNSliders:(int)number{
nSliders = number;
knobArray = nil;
[self forceRedraw];
}
-(void)forceRedraw{
[self setHidden:YES];
[self setHidden:NO];
}
@end

View File

@ -1,42 +0,0 @@
//
// Defaults.h
// eqMac
//
// Created by Romans Kisils on 12/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Logger.h"
@interface Storage : NSObject
+(void)load;
+(void)save;
+(id)get:(NSString*)key;
+(void)set:(id)object key:(NSString*)key;
+(void)setShowDefaultPresets:(BOOL)show;
+(BOOL)getShowDefaultPresets;
+(NSArray*)getSelectedGains;
+(void)setSelectedGains:(NSArray*)gains;
+(void)setSelectedCustomGains:(NSArray*)customGains;
+(NSString*)getSelectedPresetName;
+(void)setSelectedPresetName:(NSString*)name;
+(NSNumber*)getSelectedBandMode;
+(void)setSelectedBandMode:(NSNumber*)bandMode;
+(BOOL)getAppAlreadyLaunchedBefore;
+(NSString*)getUUID;
+(NSArray*)getPresetsNames;
+(void)savePresetWithName:(NSString*)name andGains:(NSArray*)gains;
+(void)deletePresetWithName:(NSString*)name;
+(NSArray*)getGainsForPresetName:(NSString*)presetName;
@end

View File

@ -1,264 +0,0 @@
//
// Defaults.m
// eqMac
//
// Created by Romans Kisils on 12/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import "Storage.h"
#import "Constants.h"
@implementation Storage
static NSString* appAlreadyLaunchedBeforeKey = @"SUHasLaunchedBefore";
static NSString* UUIDKey = @"kStorageUUID";
static NSString* showDefaultPresetsKey = @"kStorageShowDefaultPresets";
static NSString* selectedBandModeKey = @"kStorageSelectedBandMode";
static NSString* userPresets10BandsKey = @"kStoragePresets";
static NSString* userPresets31BandsKey = @"kStoragePresets31Bands";
static NSString* selectedPresetName10BandsKey = @"kStorageSelectedPresetName";
static NSString* selectedPresetName31BandsKey = @"kStorageSelectedPresetName31Bands";
static NSString* selectedGains10BandsKey = @"kStorageSelectedGains";
static NSString* selectedGains31BandsKey = @"kStorageSelectedGains31Bands";
static NSString* selectedCustomGains10BandsKey = @"kStorageSelectedCustomGains";
static NSString* selectedCustomGains31BandsKey = @"kStorageSelectedCustomGains31Bands";
static NSArray* defaultFlatGains10Bands;
static NSArray* defaultFlatGains31Bands;
static BOOL appAlreadyLaunchedBefore;
static NSString* UUID;
static BOOL showDefaultPresets;
static NSNumber* selectedBandMode;
static NSDictionary* userPresets10Bands;
static NSDictionary* userPresets31Bands;
static NSString* selectedPresetName10Bands;
static NSString* selectedPresetName31Bands;
static NSArray* selectedGains10Bands;
static NSArray* selectedGains31Bands;
static NSArray* selectedCustomGains10Bands;
static NSArray* selectedCustomGains31Bands;
+(id)get:(NSString*)key{
return [[NSUserDefaults standardUserDefaults] objectForKey: key];
}
+(void)set:(id)object key:(NSString*)key{
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
}
+(void)load{
[[NSUserDefaults standardUserDefaults] synchronize];
defaultFlatGains10Bands = @[@0,@0,@0,@0,@0,@0,@0,@0,@0,@0];
defaultFlatGains31Bands = @[@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0,@0];
// appAlreadyLaunchedBefore
NSNumber* appAlreadyLaunchedBeforeNumber = [self get: appAlreadyLaunchedBeforeKey];
if (appAlreadyLaunchedBeforeNumber == nil){
appAlreadyLaunchedBeforeNumber = @NO;
}
appAlreadyLaunchedBefore = [appAlreadyLaunchedBeforeNumber boolValue];
// UUID
UUID = [self get: UUIDKey];
if(UUID == nil){
UUID = [[NSUUID UUID] UUIDString];
}
// showDefaultPresets
NSNumber* showDefaultPresetsNumber = [self get: showDefaultPresetsKey];
if (showDefaultPresetsNumber == nil){
showDefaultPresetsNumber = @NO;
}
showDefaultPresets = [showDefaultPresetsNumber boolValue];
// selectedBandMode
selectedBandMode = [self get: selectedBandModeKey];
if (selectedBandMode == nil) selectedBandMode = @10;
//userPresets10Bands;
userPresets10Bands = [self get: userPresets10BandsKey];
if (userPresets10Bands == nil) userPresets10Bands = @{};
//userPresets31Bands;
userPresets31Bands = [self get: userPresets31BandsKey];
if (userPresets31Bands == nil) userPresets31Bands = @{};
//selectedPresetName10Bands;
selectedPresetName10Bands = [self get: selectedPresetName10BandsKey];
if (selectedPresetName10Bands == nil) selectedPresetName10Bands = @"Flat";
//selectedPresetName31Bands;
selectedPresetName31Bands = [self get: selectedPresetName31BandsKey];
if (selectedPresetName31Bands == nil) selectedPresetName31Bands = @"Flat";
//selectedGains10Bands;
selectedGains10Bands = [self get: selectedGains10BandsKey];
if (selectedGains10Bands == nil) selectedGains10Bands = [defaultFlatGains10Bands copy];
//selectedGains10Bands;
selectedGains31Bands = [self get: selectedGains31BandsKey];
if (selectedGains31Bands == nil) selectedGains31Bands = [defaultFlatGains31Bands copy];
//selectedCustomGains10Bands;
selectedCustomGains10Bands = [self get: selectedCustomGains10BandsKey];
if (selectedCustomGains10Bands == nil) selectedCustomGains10Bands = [defaultFlatGains10Bands copy];
//selectedCustomGains10Bands;
selectedCustomGains31Bands = [self get: selectedCustomGains31BandsKey];
if (selectedCustomGains31Bands == nil) selectedCustomGains31Bands = [defaultFlatGains31Bands copy];
[self save];
}
+(void)save{
[self set: UUID key: UUIDKey];
[self set: [NSNumber numberWithBool: showDefaultPresets] key: showDefaultPresetsKey];
[self set: selectedBandMode key: selectedBandModeKey];
[self set: userPresets10Bands key: userPresets10BandsKey];
[self set: userPresets31Bands key: userPresets31BandsKey];
[self set: selectedPresetName10Bands key: selectedPresetName10BandsKey];
[self set: selectedPresetName31Bands key: selectedPresetName31BandsKey];
[self set: selectedGains10Bands key: selectedGains10BandsKey];
[self set: selectedGains31Bands key: selectedGains31BandsKey];
[self set: selectedCustomGains10Bands key: selectedCustomGains10BandsKey];
[self set: selectedCustomGains31Bands key: selectedCustomGains31BandsKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//kStorageAlreadyLaunched,
+(BOOL)getAppAlreadyLaunchedBefore{
return appAlreadyLaunchedBefore;
}
//UUID
+(NSString*)getUUID{
return UUID;
}
// Show Default Presets
+(void)setShowDefaultPresets:(BOOL)show{
showDefaultPresets = show;
}
+(BOOL)getShowDefaultPresets{
return showDefaultPresets;
}
// Selected Band Mode
+(void)setSelectedBandMode:(NSNumber*)mode{
selectedBandMode = mode;
}
+(NSNumber*)getSelectedBandMode{
return selectedBandMode;
}
// Selected Preset Name
+(NSString*)getSelectedPresetName{
return [selectedBandMode intValue] == 10 ? selectedPresetName10Bands : selectedPresetName31Bands;
}
+(void)setSelectedPresetName:(NSString*)presetName{
if ([selectedBandMode intValue] == 10){
selectedPresetName10Bands = presetName;
} else {
selectedPresetName31Bands = presetName;
}
}
+(NSArray*)getSelectedGains{
return [selectedBandMode intValue] == 10 ? selectedGains10Bands : selectedGains31Bands;
}
+(void)setSelectedGains:(NSArray*)gains{
if ([selectedBandMode intValue] == 10){
selectedGains10Bands = gains;
} else {
selectedGains31Bands = gains;
}
}
+(NSArray*)getFlatGains{
return [selectedBandMode intValue] == 10 ? defaultFlatGains10Bands : defaultFlatGains31Bands;
}
+(NSArray*)getSelectedCustomGains{
return [selectedBandMode intValue] == 10 ? selectedCustomGains10Bands : selectedCustomGains31Bands;
}
+(void)setSelectedCustomGains:(NSArray*)customGains{
if ([selectedBandMode intValue] == 10){
selectedCustomGains10Bands = customGains;
} else {
selectedCustomGains31Bands = customGains;
}
}
// Presets
+(NSDictionary*)getDefaultPresets{
NSMutableDictionary *defaultPresets = [[NSMutableDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"defaultPresets" ofType:@"plist"]];
NSMutableDictionary* result = [[NSMutableDictionary alloc] init];
for(NSString* key in defaultPresets){
[result setObject:[defaultPresets objectForKey:key] forKey:key];
}
return result;
}
+(NSDictionary*)getUserPresets{
return [selectedBandMode intValue] == 10 ? userPresets10Bands : userPresets31Bands;
}
+(void)setUserPresets:(NSDictionary*)presets{
if ([selectedBandMode intValue] == 10) {
userPresets10Bands = presets;
} else {
userPresets31Bands = presets;
}
}
+(NSDictionary*)getPresets{
int bandMode = [[self getSelectedBandMode] intValue];
NSMutableDictionary *presets = [@{} mutableCopy];
BOOL showDefaultPresets = bandMode == 10 ? [self getShowDefaultPresets] : false;
if (showDefaultPresets) [presets addEntriesFromDictionary: [self getDefaultPresets]];
[presets addEntriesFromDictionary: [self getUserPresets]];
[presets setObject: [self getFlatGains] forKey:@"Flat"];
[presets setObject: [self getSelectedCustomGains] forKey:@"Custom"];
return presets;
}
+(NSArray*)getPresetsNames{
return [[self getPresets] allKeys];
}
+(void)savePresetWithName:(NSString*)name andGains:(NSArray*)gains{
[Logger log: [NSString stringWithFormat: @"Storage: saving preset with name: %@ and gains: %@", name, gains]];
NSMutableDictionary *userPresets = [[self getUserPresets] mutableCopy];
[userPresets setObject: @{ @"gains": gains, @"default" : @NO } forKey: name];
[self setUserPresets:userPresets];
}
+(void)deletePresetWithName:(NSString*)name{
NSMutableDictionary *userPresets = [[self getUserPresets] mutableCopy];
[userPresets removeObjectForKey: name];
[self setUserPresets: userPresets];
}
// Preset Gains
+(NSArray*)getGainsForPresetName:(NSString*)presetName{
if ([presetName isEqualToString:@"Custom"]) return [self getSelectedCustomGains];
if ([presetName isEqualToString:@"Flat"]) return [self getFlatGains];
NSArray *gains = [[[self getPresets] objectForKey: presetName] objectForKey:@"gains"];
if (gains == nil) {
[Logger error: [NSString stringWithFormat: @"Storage: Could not find Preset gains for Preset Name: %@", presetName]];
NSMutableArray *gains = [@[] mutableCopy];
for (int i = 0; i < [[self getSelectedBandMode] intValue]; i++)
[gains addObject:@0];
}
return gains;
}
@end

View File

@ -1,36 +0,0 @@
//
// Utilities.h
// eqMac
//
// Created by Romans Kisils on 11/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "STPrivilegedTask.h"
#import "Storage.h"
#import <CommonCrypto/CommonDigest.h>
@interface Utilities : NSObject
+(BOOL)runShellScriptWithName:(NSString*)scriptName;
+(void)runAppleScriptWithName:(NSString*)scriptName;
+(NSImage *)flipImage:(NSImage *)image;
+(CGFloat)mapValue:(CGFloat) x withInMin:(CGFloat) in_min InMax:(CGFloat) in_max OutMin:(CGFloat) out_min OutMax:(CGFloat) out_max;
+(NSString*)getOSXVersion;
+(NSString*)getMacModel;
+(NSString*)getAppVersion;
+(NSModalResponse)showAlertWithTitle:(NSString*) title andMessage:(NSString *)message andButtons:(NSArray*)buttons;
+(NSString*)showAlertWithInputAndTitle:(NSString*) title;
+(void)openBrowserWithURL:(NSString*)url;
+(BOOL)isDarkMode;
+(void)executeBlock:(void(^)(void))block after:(CGFloat)seconds;
+(NSTimer *)executeBlock:(void(^)(void))block every:(CGFloat)seconds;
+ (BOOL)launchOnLoginForBundlePath:(NSString*)bundlePath;
+ (BOOL)launchOnLogin;
+ (void)setLaunchOnLogin:(BOOL)launchOnLogin forBundlePath:(NSString*)bundlePath;
+ (void)setLaunchOnLogin:(BOOL)launchOnLogin;
+ (BOOL)appWithBundleIdentifierIsRunning:(NSString*)bundleIdentifier;
+(NSArray*)orderedStringArrayFromStringArray:(NSArray*)stringArray;
+(NSString*)stringifyAnything:(id)anything;
+(NSString*)hashString:(NSString*)string;
@end

View File

@ -1,295 +0,0 @@
//
// Utilities.m
// eqMac
//
// Created by Romans Kisils on 11/12/2016.
// Copyright © 2016 bitgapp. All rights reserved.
//
#import "Utilities.h"
#import <IOKit/IOKitLib.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#import <CommonCrypto/CommonDigest.h>
@implementation Utilities
+(BOOL)runShellScriptWithName:(NSString*)scriptName{
NSString *resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
NSString *scriptExtension = @"sh";
NSString *scriptAbsolutePath = [NSString stringWithFormat:@"%@/%@.%@", resourcePath, scriptName, scriptExtension];
NSArray *argv = [NSArray arrayWithObjects:nil];
STPrivilegedTask *task = [[STPrivilegedTask alloc] init];
[task setLaunchPath:scriptAbsolutePath];
NSLog(@"%@", scriptAbsolutePath);
[task setArguments:argv];
OSStatus err = [task launch];
[task waitUntilExit];
return err == errAuthorizationSuccess;
}
+(void)getOutputData:(NSNotification *)aNotification {
//get data from notification
NSLog(@"NOTIFY!");
NSData *data = [[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSLog(@"%@", data);
//make sure there's actual data
if ([data length]) {
// do something with the data
NSString *outputString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", outputString);
// go read more data in the background
[[aNotification object] readInBackgroundAndNotify];
} else {
// do something else
}
}
+(void)runAppleScriptWithName:(NSString*)scriptName{
NSString *resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
NSString *scriptExtension = @"scpt";
NSString *scriptAbsolutePath = [NSString stringWithFormat:@"%@/%@.%@", resourcePath, scriptName, scriptExtension];
NSURL* url = [NSURL fileURLWithPath:scriptAbsolutePath];
NSDictionary* errors = [NSDictionary dictionary];
NSAppleScript* appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];
[appleScript executeAndReturnError:nil];
}
+(NSString*)generateUUID{
return [[NSUUID UUID] UUIDString];
}
+ (NSImage *)flipImage:(NSImage *)image
{
NSImage *existingImage = image;
NSSize existingSize = [existingImage size];
NSSize newSize = NSMakeSize(existingSize.width, existingSize.height);
NSImage *flipedImage = [[NSImage alloc] initWithSize:newSize];
[flipedImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
NSAffineTransform *t = [NSAffineTransform transform];
[t translateXBy:existingSize.width yBy:existingSize.height];
[t scaleXBy:-1 yBy:-1];
[t concat];
[existingImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1.0];
[flipedImage unlockFocus];
return flipedImage;
}
+(NSString*)getOSXVersion{
NSProcessInfo *pInfo = [NSProcessInfo processInfo];
NSArray *versionArray = [[pInfo operatingSystemVersionString] componentsSeparatedByString:@" "];
if([versionArray count] >= 2) return [versionArray objectAtIndex:1];
return @"Unidentified";
}
+(NSString*)getMacModel{
size_t len = 0;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
if (len){
char *model = malloc(len*sizeof(char));
sysctlbyname("hw.model", model, &len, NULL, 0);
NSString *model_ns = [NSString stringWithUTF8String:model];
free(model);
return model_ns;
}
return @"Unidentified Apple Computer"; //incase model name can't be read
}
+(NSString*)getAppVersion{
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
}
+(CGFloat)mapValue:(CGFloat) x withInMin:(CGFloat) in_min InMax:(CGFloat) in_max OutMin:(CGFloat) out_min OutMax:(CGFloat) out_max{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
+(NSModalResponse)showAlertWithTitle:(NSString*) title andMessage:(NSString *)message andButtons:(NSArray*)buttons{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText: title];
[alert setInformativeText: message];
for(NSString *buttonTitle in buttons){
[alert addButtonWithTitle:buttonTitle];
}
return alert.runModal;
}
+(NSString *)showAlertWithInputAndTitle:(NSString*) title{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText: title];
[alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"];
NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[input setStringValue:@""];
[alert setAccessoryView:input];
[alert runModal];
[input becomeFirstResponder];
[input validateEditing];
return input.stringValue;
}
+(void)openBrowserWithURL:(NSString*)url{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}
+(BOOL)isDarkMode{
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain];
id style = [dict objectForKey:@"AppleInterfaceStyle"];
BOOL darkModeOn = ( style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] );
return darkModeOn;
}
+(void)executeBlock:(void(^)(void))block after:(CGFloat)seconds{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), dispatch_get_main_queue(), block);
}
+(NSTimer *)executeBlock:(void(^)(void))block every:(CGFloat)seconds{
return [NSTimer scheduledTimerWithTimeInterval:seconds
target:[NSBlockOperation blockOperationWithBlock:block]
selector:@selector(main)
userInfo:nil
repeats:YES];
}
+ (BOOL)launchOnLoginForBundlePath:(NSString*)bundlePath{
LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
CFArrayRef snapshotRef = LSSharedFileListCopySnapshot(loginItemsListRef, NULL);
NSArray* loginItems = (__bridge NSArray*) snapshotRef;
NSURL *bundleURL = [NSURL fileURLWithPath: bundlePath];
for (id item in loginItems) {
LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
CFURLRef itemURLRef;
if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) {
NSURL *itemURL = (__bridge NSURL *)itemURLRef;
if ([itemURL isEqual:bundleURL]) {
return YES;
}
}
}
return NO;
}
+ (BOOL)launchOnLogin{
return [self launchOnLoginForBundlePath: [[NSBundle mainBundle] bundlePath]];
}
+ (void)setLaunchOnLogin:(BOOL)launchOnLogin forBundlePath:(NSString*)bundlePath{
NSURL *bundleURL = [NSURL fileURLWithPath: bundlePath];
LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (launchOnLogin) {
NSDictionary *properties;
properties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"com.apple.loginitem.HideOnLaunch"];
LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsListRef, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)bundleURL, (__bridge CFDictionaryRef)properties,NULL);
if (itemRef) {
CFRelease(itemRef);
}
} else {
LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
CFArrayRef snapshotRef = LSSharedFileListCopySnapshot(loginItemsListRef, NULL);
NSArray* loginItems = (__bridge NSArray*) snapshotRef;
for (id item in loginItems) {
LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
CFURLRef itemURLRef;
if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) {
NSURL *itemURL = (__bridge NSURL *) itemURLRef;
if ([itemURL isEqual:bundleURL]) {
LSSharedFileListItemRemove(loginItemsListRef, itemRef);
}
}
}
}
}
+ (void)setLaunchOnLogin:(BOOL)launchOnLogin{
[self setLaunchOnLogin:launchOnLogin forBundlePath: [[NSBundle mainBundle] bundlePath]];
}
+ (BOOL)appWithBundleIdentifierIsRunning:(NSString*)bundleIdentifier{
NSArray *runningApplications = [[NSWorkspace sharedWorkspace] runningApplications];
for (NSRunningApplication *application in runningApplications) {
if ([[application bundleIdentifier] isEqualToString: bundleIdentifier]) return true;
}
return false;
}
+(NSString *) md5:(NSString *) input{
const char *cStr = [input UTF8String];
unsigned char digest[16];
CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
+(int)getDaysUntilDate:(NSDate*)date{
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay
fromDate:[NSDate date]
toDate:date
options:0];
return (int)[components day];
}
+(NSDate*)NSDateFromISO:(NSString*)iso{
NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
[dateFormat setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
[dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSDate *date = [dateFormat dateFromString:iso];
return date;
}
+(NSString*)readableDateFromNSDate:(NSDate*)date{
return [NSDateFormatter localizedStringFromDate:date
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterFullStyle];
}
+(NSArray*)orderedStringArrayFromStringArray:(NSArray*)stringArray{
return [stringArray sortedArrayUsingComparator:^NSComparisonResult(NSString *firstString, NSString *secondString) {
return [[firstString lowercaseString] compare:[secondString lowercaseString]];
}];
}
+(NSString*)stringifyAnything:(id)anything{
if ([@[NSArray.class, NSMutableArray.class, NSDictionary.class, NSMutableDictionary.class] containsObject: [anything class]] ){
return [[NSString alloc] initWithData: [NSJSONSerialization dataWithJSONObject:anything options:(NSJSONWritingOptions) NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
}
return anything;
}
+(NSString*)hashString:(NSString*)string{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (CC_LONG) data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++){
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
@end

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<collectionViewItem id="YoL-Kx-f86"/>
<customObject id="dKN-XH-Lfb" customClass="SUUpdater"/>
</objects>
</document>

View File

@ -1,402 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Flat</key>
<dict>
<key>default</key>
<false/>
<key>gains</key>
<array>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
</array>
</dict>
<key>Accoustic</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.172916666667</real>
<real>0.204166666667</real>
<real>-0.326666666667</real>
<real>0.04375</real>
<real>0.379583333333</real>
<real>0.07291666666670001</real>
<real>0.145833333333</real>
<real>0.170833333333</real>
<real>0.147916666667</real>
<real>0.0895833333333</real>
</array>
</dict>
<key>Bass Booster</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.229166666667</real>
<real>0.177083333333</real>
<real>0.145833333333</real>
<real>0.104166666667</real>
<real>0.0520833333333</real>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
</array>
</dict>
<key>Bass Reducer</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.229166666667</real>
<real>-0.177083333333</real>
<real>-0.145833333333</real>
<real>-0.104166666667</real>
<real>-0.0520833333333</real>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
</array>
</dict>
<key>Classic </key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.197916666667</real>
<real>0.15625</real>
<real>0.125</real>
<real>0.104166666667</real>
<real>-0.0625</real>
<real>-0.0625</real>
<integer>0</integer>
<real>0.09375</real>
<real>0.135416666667</real>
<real>0.15625</real>
</array>
</dict>
<key>Dance</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.14875</real>
<real>0.272916666667</real>
<real>0.207916666667</real>
<integer>0</integer>
<real>0.08</real>
<real>0.152083333333</real>
<real>0.214583333333</real>
<real>0.189166666667</real>
<real>0.149583333333</real>
<integer>0</integer>
</array>
</dict>
<key>Deep</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.20625</real>
<real>0.147916666667</real>
<real>0.07291666666670001</real>
<real>0.0416666666667</real>
<real>0.11875</real>
<real>0.104166666667</real>
<real>0.0604166666667</real>
<real>-0.0895833333333</real>
<real>-0.147916666667</real>
<real>-0.191666666667</real>
</array>
</dict>
<key>Electronic</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.177083333333</real>
<real>0.158333333333</real>
<real>0.05</real>
<integer>0</integer>
<real>-0.0895833333333</real>
<real>0.09375</real>
<real>0.0354166666667</real>
<real>0.0520833333333</real>
<real>0.164583333333</real>
<real>0.2</real>
</array>
</dict>
<key>Hip-Hop</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.208333333333</real>
<real>0.177083333333</real>
<real>0.0625</real>
<real>0.125</real>
<real>-0.0416666666667</real>
<real>-0.0416666666667</real>
<real>0.0625</real>
<real>-0.0208333333333</real>
<real>0.08333333333329999</real>
<real>0.125</real>
</array>
</dict>
<key>Jazz</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.166666666667</real>
<real>0.125</real>
<real>0.0625</real>
<real>0.09375</real>
<real>-0.0625</real>
<real>-0.0625</real>
<integer>0</integer>
<real>0.0625</real>
<real>0.125</real>
<real>0.15625</real>
</array>
</dict>
<key>Latin</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.1875</real>
<real>0.125</real>
<integer>0</integer>
<integer>0</integer>
<real>-0.0625</real>
<real>-0.0625</real>
<real>-0.0625</real>
<integer>0</integer>
<real>0.125</real>
<real>0.1875</real>
</array>
</dict>
<key>Loudness</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.25</real>
<real>0.166666666667</real>
<integer>0</integer>
<integer>0</integer>
<real>-0.08333333333329999</real>
<integer>0</integer>
<real>-0.0416666666667</real>
<real>-0.208333333333</real>
<real>0.208333333333</real>
<real>0.0416666666667</real>
</array>
</dict>
<key>Lounge</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.125</real>
<real>-0.0625</real>
<real>-0.0208333333333</real>
<real>0.0625</real>
<real>0.166666666667</real>
<real>0.104166666667</real>
<integer>0</integer>
<real>-0.0625</real>
<real>0.08333333333329999</real>
<real>0.0416666666667</real>
</array>
</dict>
<key>Piano</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.125</real>
<real>0.08333333333329999</real>
<integer>0</integer>
<real>0.104166666667</real>
<real>0.125</real>
<real>0.0625</real>
<real>0.145833333333</real>
<real>0.1875</real>
<real>0.125</real>
<real>0.145833333333</real>
</array>
</dict>
<key>Pop</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.0625</real>
<real>-0.0416666666667</real>
<integer>0</integer>
<real>0.08333333333329999</real>
<real>0.166666666667</real>
<real>0.166666666667</real>
<real>0.08333333333329999</real>
<integer>0</integer>
<real>-0.0416666666667</real>
<real>-0.0625</real>
</array>
</dict>
<key>RnB</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.109166666667</real>
<real>0.288333333333</real>
<real>0.235416666667</real>
<real>0.0554166666667</real>
<real>-0.09125</real>
<real>-0.0625</real>
<real>0.0966666666667</real>
<real>0.110416666667</real>
<real>0.125</real>
<real>0.15625</real>
</array>
</dict>
<key>Rock</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.208333333333</real>
<real>0.166666666667</real>
<real>0.125</real>
<real>0.0625</real>
<real>-0.0208333333333</real>
<real>-0.0416666666667</real>
<real>0.0208333333333</real>
<real>0.104166666667</real>
<real>0.145833333333</real>
<real>0.1875</real>
</array>
</dict>
<key>Small Speakers</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>0.229166666667</real>
<real>0.177083333333</real>
<real>0.145833333333</real>
<real>0.104166666667</real>
<real>0.0520833333333</real>
<integer>0</integer>
<real>-0.0520833333333</real>
<real>-0.104166666667</real>
<real>-0.145833333333</real>
<real>-0.177083333333</real>
</array>
</dict>
<key>Spoken Word</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.144166666667</real>
<real>-0.0195833333333</real>
<integer>0</integer>
<real>0.02875</real>
<real>0.144166666667</real>
<real>0.192083333333</real>
<real>0.201666666667</real>
<real>0.178333333333</real>
<real>0.105833333333</real>
<integer>0</integer>
</array>
</dict>
<key>Treble Booster</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<real>0.0520833333333</real>
<real>0.104166666667</real>
<real>0.145833333333</real>
<real>0.177083333333</real>
<real>0.229166666667</real>
</array>
</dict>
<key>Treble Reducer</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<integer>0</integer>
<real>-0.0520833333333</real>
<real>-0.104166666667</real>
<real>-0.145833333333</real>
<real>-0.177083333333</real>
<real>-0.229166666667</real>
</array>
</dict>
<key>Vocal Booster</key>
<dict>
<key>default</key>
<true/>
<key>gains</key>
<array>
<real>-0.0625</real>
<real>-0.125</real>
<real>-0.125</real>
<real>0.0625</real>
<real>0.15625</real>
<real>0.15625</real>
<real>0.125</real>
<real>0.0625</real>
<integer>0</integer>
<real>-0.0625</real>
</array>
</dict>
</dict>
</plist>

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>17B1003</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>eqMac2Driver</string>
<key>CFBundleIdentifier</key>
<string>com.bitgapp.eqMac2Driver</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>1.0</string>
<key>CFBundleName</key>
<string>eqMac2Driver</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>2.0</string>
<key>CFBundleSignature</key>
<string>sFlo</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>2.0</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>9C40b</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>17C76</string>
<key>DTSDKName</key>
<string>macosx10.13</string>
<key>DTXcode</key>
<string>0920</string>
<key>DTXcodeBuild</key>
<string>9C40b</string>
<key>IOKitPersonalities</key>
<dict>
<key>PhantomAudioDriver</key>
<dict>
<key>AudioEngines</key>
<array>
<dict>
<key>BlockSize</key>
<integer>8192</integer>
<key>Description</key>
<string>eqMac2</string>
<key>Formats</key>
<array>
<dict>
<key>IOAudioStreamAlignment</key>
<integer>1</integer>
<key>IOAudioStreamBitDepth</key>
<integer>32</integer>
<key>IOAudioStreamBitWidth</key>
<integer>32</integer>
<key>IOAudioStreamByteOrder</key>
<integer>0</integer>
<key>IOAudioStreamDriverTag</key>
<integer>0</integer>
<key>IOAudioStreamIsMixable</key>
<integer>1</integer>
<key>IOAudioStreamNumChannels</key>
<integer>2</integer>
<key>IOAudioStreamNumericRepresentation</key>
<integer>1936289396</integer>
<key>IOAudioStreamSampleFormat</key>
<integer>1819304813</integer>
</dict>
</array>
<key>NumBlocks</key>
<integer>2</integer>
<key>NumStreams</key>
<integer>1</integer>
<key>SampleRates</key>
<array>
<integer>44100</integer>
<integer>48000</integer>
<integer>88200</integer>
<integer>96000</integer>
<integer>176400</integer>
<integer>192000</integer>
</array>
</dict>
</array>
<key>CFBundleIdentifier</key>
<string>com.bitgapp.eqMac2Driver</string>
<key>IOClass</key>
<string>com_bitgapp_eqMac2Driver</string>
<key>IOMatchCategory</key>
<string>com_bitgapp_eqMac2Driver</string>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.iokit.IOAudioFamily</key>
<string>1.1fc6</string>
<key>com.apple.kpi.iokit</key>
<string>8.0</string>
<key>com.apple.kpi.libkern</key>
<string>8.0</string>
<key>com.apple.kpi.mach</key>
<string>8.0</string>
</dict>
</dict>
</plist>

View File

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>17A365</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>eqMac2Helper</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<key>CFBundleIdentifier</key>
<string>com.bitgapp.eqMac2Helper</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>eqMac2Helper</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>9A235</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>17A360</string>
<key>DTSDKName</key>
<string>macosx10.13</string>
<key>DTXcode</key>
<string>0900</string>
<key>DTXcodeBuild</key>
<string>9A235</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>10.10</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 Romans Kisils. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More