Closed ekarlo closed 4 years ago
I knew it was in the ring buffer! Well done @ekarlo ! BRAVO! I will try to build and report back!
A new version of eqMac is exciting news. Most of us will be unable to compile for ourselves so we would need you to post a compiled version if and when you feel it's ready.
One of the most common problems people seem to be having with 2.2 is a random reset of the audio volume both upon starting the app as well as after certain other events, like switching from headphone jack to internal speakers. A fix for that alone would make many people very happy.
I've fixed no sound issue on my mac running Catalina 10.15.2 at pull request https://github.com/ekarlo/eqMac2/pull/1 Tks @ekarlo, I've using it without any issue.
I read through this and didn't understand much of what you said, but a fix to the static bug is amazing!! It's been my only gripe with the program. From the perspective of someone who doesn't use terminal or Xcode, is this easy to set up? Or should I wait until a compiled version can be made, like someone else mentioned? I feel like I'd mess something up doing all those complicated steps.
Hey everyone. Excuse me for the lack of updates. I have been really busy on the new version of eqMac. I am happy to announce an open beta release. You can download it here: https://eqmac.app There are a lot of known bugs that I could not fix just yet:
So as you can see there's still some work to be done but at least it's a completely modern tech stack that I am fully willing to work on: 100% Swift, User Space driver and a Web UI, instead of C++, Kernel Drivers. As I said, should work on Catalina and should not have any pesky ear drum blasting volume bugs (at least I didn't come across any). I'm open to feedback and issue reports here: https://github.com/bitgapp/eqmac That repo will become the main repo for eqMac and this repo will be archived eventually. And yes it's called just eqMac, not eqMac3 :) And it will stay that way forever.
I have placed a build of eqMac2 v2.3.2 in: https://github.com/ekarlo/eqMac2/blob/master/eqMac2/Dist/eqMac2-2.3.2.zip Clicking on this will display a Download button.
Download Decompress Move eqMac2-2.3.2/eqMac2.app as desired (maybe /Applications/) Drag to Dock as desired Run
This is a test build based on the current source and not an official release. eqMac2 v2.2 - current release version on nodeful eqMac2 v2.3 - test version with liscio ring buffer and modified install scripts eqMac2 v2.3.1 - test version incorporating 2 changes by tdvhoang eqMac2 v2.3.2 - test version rollback of change 1 in v2.3.1 - test release
This was built with the signing described in the first comment. I assume the os can be convinced to run it. If anyone tries this it would be interesting to hear about any install experience and if it works on Catalina better. Also if it works.
nodeful - My recommendation, if I may, is to make a new final release, say v2.4, with the changes in v2.3.2 and call it done. If this thing was a truck v2.2 would run for a while then end up on the shoulder with a smoking seized engine and v2.3, with a simple change, cruises smoothly in the fast lane, all day.
This would allow a good end to this phase of this very fine project and free up some brain cells for the new effort.
@ekarlo
Download Decompress Move eqMac2-2.3.2/eqMac2.app as desired (maybe /Applications/) Drag to Dock as desired Run
Unfortunately, after these steps and installing, I get no sound through my headphones (running Catalina). But I agree, I think this fix should be implemented and then can be moved past. To be honest, I would probably stick with this version as opposed to the new one simply because of preference of interface design.
@andrewmorner The no sound problem was reported by tdvhoang (above) and a fix was provided however I found that after a while the sync/distortion bug returned along with a flood of error messages in the Xcode console, this time with a multi-per-second flutter, and the fix was backed out. I've had no problems under Mojave 10.14.6 and tdvhoang reports success under Catalina, with a fix.
I rebuilt the tdvhoang version v2.3.1 and placed it at: https://github.com/ekarlo/eqMac2/blob/master/eqMac2/Dist/eqMac2-2.3.1.zip It would be interesting if you could try this version and see if works.
On a side note, using techno and edm for testing is problematic in that it can sometimes be hard to tell the difference between the music and software failure.
@ekarlo Thanks for spending time on this! So it worked for about 10 minutes but then right after a certain point, the audio got super choppy and I had to reset it. No gradual distortion like the normal build, but more of like an immediate choppiness out of nowhere.
@andrewmorner Had exact same problem. Looks like more of the liscio ring buffer code needed to be copied in addition to CARingBuffer.cpp and CARingBuffer.h.
Placed a new build of eqMac2 v2.3.3 in: https://github.com/ekarlo/eqMac2/blob/master/eqMac2/Dist/eqMac2-2.3.3.zip
Code of interest is in EQEngine.mm function outputProc() (modification of Apple CAPlayThrough example). The "Fetch" gets samples from the ring buffer. (There is a corresponding inputProc function with a "Store" into the ring buffer.)
Old Code ---
//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;
The change made by tdvhoang moved the checkError() call and allowed it to work for a few minutes. This pointed to where the problem was, looked at the code in the liscio version, copied it over and made the v2.3.3 test release.
New Code from liscio verion ---
//copy the data from the buffers
err = This->mBuffer->Fetch(ioData, inNumberFrames,
SInt64(TimeStamp->mSampleTime - This->mInToOutSampleOffset));
if (err != kCARingBufferError_OK ) {
SInt64 bufferStartTime, bufferEndTime;
This->mBuffer->GetTimeBounds( bufferStartTime, bufferEndTime );
CAPT_DEBUG( "Oops. Adjusting IOOffset from %f, ", This->mInToOutSampleOffset );
if ( err < kCARingBufferError_OK ) {
CAPT_DEBUG( "ahead " );
if ( err == kCARingBufferError_WayBehind ) {
MakeBufferSilent( ioData );
}
This->mInToOutSampleOffset += std::max( ( TimeStamp->mSampleTime - This->mInToOutSampleOffset ) - bufferStartTime, kAdjustmentOffsetSamples );
}
else if ( err > kCARingBufferError_OK ) {
CAPT_DEBUG( "behind " );
if ( err == kCARingBufferError_WayAhead ) {
MakeBufferSilent( ioData );
}
// Adjust by the amount that we read past in the buffer
This->mInToOutSampleOffset += std::max( ( ( TimeStamp->mSampleTime - This->mInToOutSampleOffset ) + inNumberFrames ) - bufferEndTime, kAdjustmentOffsetSamples );
}
CAPT_DEBUG( "to %f.\n", This->mInToOutSampleOffset );
MakeBufferSilent ( ioData );
}
return noErr;
And here are the error codes returned by the ring buffer fetch call. Seems like something profound encoded in these numbers. Almost like a law of the universe:
enum {
kCARingBufferError_WayBehind = -2, // both fetch times are earlier than buffer start time
kCARingBufferError_SlightlyBehind = -1, // fetch start time is earlier than buffer start time (fetch end time OK)
kCARingBufferError_OK = 0,
kCARingBufferError_SlightlyAhead = 1, // fetch end time is later than buffer end time (fetch start time OK)
kCARingBufferError_WayAhead = 2, // both fetch times are later than buffer end time
kCARingBufferError_TooMuch = 3, // fetch start time is earlier than buffer start time and fetch end time is later than buffer end time
kCARingBufferError_CPUOverload = 4 // the reader is unable to get enough CPU cycles to capture a consistent snapshot of the time bounds
};
@ekarlo
You've done it!! Been running it now for hours consecutively with no distortion. You're awesome, thanks a ton.
Excellent. I thought it would work but didn't want to jinx it by saying so. After all I are a computer scientist and being superstitious is bad luck, right?
Anyway, I consider the Static/sync loss and the Catalina install issues solved (contributions from @liscio, @tdvhoang and @andrewmorner) and this issue #180 and the following issues can be marked closed:
Support for macOS Catalina 10.15 #172 Not able to install eqmac2 driver on 16 inch MacBook Pro even with security settings disabled #179 EQMac2 requires a driver update!!! #177 Inadequate bit depth settings causing clock frequency/bit drift (ie: crackling or cracking) #174 Support for macOS Catalina 10.15 #172 no sound on boot, general hardware issues, call for dev contributions #166 How to clean uninstall / crackling sound #156 Sound is crackling (Mojave) #152 Syncing problem #144 eqMac2 crashes after mac wakes up from sleep mode #134 Sounds starts crackling and after a while completely turns off. #79 Sounds degrade after 30 minutes playing aprox. #36 Still problems with Mac restart and 2.0.6 version eqMac2 #27
Files changed are:
eqMac2/Libs/CARingBuffer/CARingBuffer.cpp
eqMac2/Libs/CARingBuffer/CARingBuffer.h
eqMac2/Source/EQEngine/EQEngine.h
eqMac2/Source/EQEngine/EQEngine.mm
eqMac2/Source/Scripts/install_driver.sh
eqMac2/Source/Scripts/uninstall_driver.sh
eqMac2/Supporting files/Info.plist
To see all changes between the release version 2.2 and test version 2.3.3 from command line do:
mkdir someworkdir
cd someworkdir
git clone https://github.com/ekarlo/eqMac2.git eqMac2ekarlo
git clone https://github.com/nodeful/eqMac2.git eqMac2nodeful
diff -r -x .git eqMac2ekarlo eqMac2nodeful | less
If these changes can be captured into the v2.2 base and a new version released the 2.3 test clone can be deleted.
I just wanted to say thank you to @ekarlo. It's been working great so far and I uninstalled Boom 2.
I was/am a paying customer of Boom2, but I never truly loved the product, it was just there. I've always been looking for an OSS solution.
Thanks everyone to this great program esp @nodeful!
[EDIT] I just picked up a pair of Airpod Pros. The Airpods' automatic switching ability screws with the volume putting it to the max. Sadly, I ended up switching back to Boom 2. If anyone has experience with this feel free to chime in. Hopefully, the newer vs of eqmac will solve these issues.
Love it, thanks a lot for this release. Beautiful software, incredibly functional and important for all Mac users. Waiting for the delay fix to be able to watch videos with it.
This is awesome work guys. Never knew this even existed!!!! Working perfectly on Catalina, remember to click the "allow" button for "Roman"
I installed @ekarlo build (2.3.3) and it works perfectly.
I want to say thank to @ekarlo and everyone who helped so far.
Good job! 🤘
Hey everyone 👋 I will be open sourcing the new version of eqMac, therefore, I am closing this issue and repository as I will be transfering nodeful/eqMac2 repo to bitgapp/eqMac Please bear with me for the next couple of days as I setup that new repo. The eqMac2 code will be living in the old-eqMac2 branch if anyone is interested in referencing it for whatever reason. Please try out the new version and report bugs to the new repo. Thanks for using eqMac.
Moving discussion and tracking of this issue to #224
Invitation for confirmation of findings. Available via build and test only at this time.
For Christmas I replaced a perfectly good pair of computer speakers with a more perfectly good pair except for an irritating (but hifi) booming bass tone. Went in search of a simple equalizer app and found:
Audio Hijack - Pro level, $$, more than I was looking for.
Boom 3D - Bought it. Worked great but was concerned (wrongly it seems) about need to access the mic at full volume and unfortunately necessary copy protection.
eqMac2 - Free, open source - Saw this and since I had been wanting to learn about Xcode and Objective C, and Git, and GitHub, decided to clone and build it.
[ Several hours pass ]
Got it built and it worked fine, for a while. After a few minutes the output would start to degrade and after about 30 minutes output would cease. Found that release v2.2 also failed and this was a reported issue. Decided to try and narrow down where the failure was happening.
Under Xcode it is possible to set breakpoints but this would crash the program in a kind of “Heisenbug” effect. Even setting a breakpoint in code not being executed would disrupt the output with 4 or 5 clicks producing the same effect as letting it run for 30+ minutes. I added numerous “printf” statements (which appear on the Xcode console) to instrument the program.
I couldn’t tell exactly what was wrong let alone how to fix it but it seemed to be a buffering problem with the ring buffer (https://en.wikipedia.org/wiki/Circular_buffer).
In my searches I had noticed a project from 9 (nine!) years ago related to CAPlayThrough on which eqMac2 is based (https://github.com/liscio/CAPlayThrough) which states: Look! A version of CAPlayThrough that works... ...for the most part. Standard disclaimers apply, etc. I've cobbled together improvements to CARingBuffer.cpp and CARingBuffer.h that were based on an older version of CARingBuffer that I found in an older version of the CoreAudio SDK (Thanks, Pacifist!) There were many bugs in that class which caused havoc in the CAPlayThrough sample, especially when mixing devices that have varying sample rates (and drifting clocks.) Please: if you find bugs, try and fix them yourself, and contribute back to this repo for the benefit of others. I don't have time to respond to bug reports.
On a hunch I replaced these two modules in eqMac2 with the liscio versions and this seems to have fixed all the static/sync issues. Wake from sleep issues may also be fixed.
In addition I looked at the install problems reported under Catalina and made changes to install_driver.sh and uninstall_driver.sh to copy the driver to /Library/Extensions/ instead of /System/Library/Extensions/. I don’t have Catalina to test but reading the comments seem to point to this, or not. It seems LE is preferred over SLE in general. This will also work for older macOSs.
These simple shell scripts can be run from the command line. This will also reveal any error messages. Examine and modify as needed:
Building:
OK, on “Signing & Capabilities & Build Settings” can be a world of hurt. You can set up “Personal Team” using your Apple ID under Xcode->Preferences->Accounts to allow install on a local machine.
Under “Signing & Capabilities” I used:
Under “Build Settings” - Signing section
Also, permission to use the “eqMac2 Microphone” needs to be given. Also, make sure the mic and output volumes are not zeroed or muted. Do this often. Also, various macOS permissions may be involved. Also, these settings can interact with each other.
Bottom line - eqMac2 2.3 has been up and running for days without apparent problems and am totally satisfied with this solution. Anyone with a Mac should be able to build a working version.
All credit to the great work of Romans Kisils and Christopher Liscio.