The output now uses AVSampleBufferAudioRenderer to play all formats, and
uses that to resample. It also supports Spatial Audio on macOS 12.0 or
newer. Note that there are some outstanding bugs with Spatial Audio
support. Namely that it appears to be limited to only 192 kHz at mono or
stereo, or 352800 Hz at surround configurations. This breaks DSD64
playback at stereo formats, as well as possibly other things. This is
entirely an Apple bug. I have reported it to Apple with reference code
FB10441301 for reference, in case anyone else wants to complain that it
isn't fixed.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
All optional fallback code for older versions has also been removed, and
everything now assumes 10.13.0 or newer. Some cases are still included
for point releases, such as 10.13.2.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Redesign the code signing from the ground up. Now all bundles and their
embedded frameworks import the Shared.xcconfig file and enable its
settings, so they may be signed with Apple Development instead of sign
to run locally. This apparently isn't necessary for frameworks which are
embedded in the main app bundle directly, only for the bundles and their
frameworks.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Require asking user consent for data transmission on first launch, or
otherwise disable sending crash reports by default.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Automatically format any XML escapes of file type association names.
Adjust Info.plist to account for this change.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Plist generator now emits the output to the temporary folder, which we
have write permission to.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add dealloc function to close the file container, in case the caller
neglected to do so on its own.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Refine the output function a bit, including adding some minor safety
checks, in case the caller requests zero samples, or requests a format
with zero channels.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Move the Core Audio output function block to its own declarative
function, so that its block variables are isolated, and so that debug
traces show up in a more sensible place.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This code turned out to be somewhat of a mistake to employ, so it's now
being removed, and shall not be re-added, as it doesn't really work.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add play count data collection, including first seen times for every
file first added to the playlist. Data is indexed by album, artist, and
title, or by filename, whichever matches first. Add interfaces to
AppleScript automation definition as well.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
As it doesn't seem to work properly on Intel machines, anyway. It just
leads to pointless crashes, and doesn't seem to serve any purpose.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Restrict the use of workgroup joining and workgroup intervals to macOS
Monterey or newer, as it seems the way I use it, it's completely broken
on macOS Big Sur, which was the original minimum target for the API.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apply changes to exit the thread if workgroup initialization or joining
fails, instead of attempting to continue executing the thread.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add an extra step to the workgroup exit call, so that it only calls to
leave if the join token is valid, or at least initialized.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Fix a potential bug where the device enumerator would return a nil
device name string, which would result in a crash. Instead, report an
unknown numbered device.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
It was a fun ride, but I think I want to try something different. Users,
please be sure not to have DNS blocking for Crashlytics if you want me
to have any useful bug reporting info if it crashes on you, or otherwise
blows up. Otherwise, I don't get any useful data to help me fix crashes.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Synchronize audio setup and audio stopping on the object's own pointer,
to hopefully prevent race conditions with out of sync calls to the stop
function from both the main and the audio thread.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The changes include no longer leaving the workgroup for seeking or for
converter format changes, and also still leaving the workgroup on thread
termination if there was an error with intervals starting or finishing.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
An impulse cache reduces any glitching from format channel count changes
to near insignificant levels, resulting in a more pleasant experience
when there are different mixed formats playing, or even a file which
changes format mid-playback.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Ensure that dynamic info updates, even on static files, only update the
exact track they apply to, by atomically assigning the userInfo property
before opening the decoder, so that callbacks to the player indicate the
correct track and don't assume it's the one that's currently visibly
playing. Fixes start of track metadata notifications from overwriting
the previously playing track.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Various warnings related to uninitialized variables, or setting values
to variables that would not be used later or would be overwritten by per
loop initializers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Surprised I didn't catch this sooner. This could have resulted in a
division by zero error if either sample rate somehow was zero.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
DFT should use aligned memory blocks for best results. Also allocate one
extra sample for DFT output, just in case DFT zop is as bad as zrop.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
DFT float happens to clobber one extra sample on forward translate, so
allocate one extra for every complex buffer.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Work back to a vDSP implementation, this time using overlap-save instead
of overlap-add, also accumulating the results as complex values, only
inversing them once at the end, and finally, replacing the FFT method
with the newer DFT API.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Only uninitialize the equalizer if sound output was successfully started
and the equalizer AudioUnit was successfully ininitialized.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
When leaving the workgroup, clear the token, as the join call requires
the token to be uninitialized.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Errors should stop all attempts to further use the audio thread priority
code, so there won't be debug breakpoints called on older OSes.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
As the decimator has shown to be twice as loud as it should be, the
volume should be reduced by half when converting DSD to PCM with it.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Pure downsampling is slower, but may or may not be more accurate. Though
probably not worth it. It did help me realize a minor error, though.
The decimator's volume is twice as loud as it should be.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This prevents crashes where inputs were not returning either properties
or metadata blocks and the file open cache was attempting to cache the
resulting nil pointer as if it were valid. Also prevent the metadata
redundant string coalescing from processing nil objects as well, in case
it's used that way somewhere else.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Set baseline real-time priority for audio threads even on old macOS,
since that API is available there. Only set it once, and do not attempt
again if it fails, only once per thread.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
I'm not sure about macOS Ventura, but stable releases of macOS, at
least on Intel, require that threads joining Audio Interval
workgroups already be set to run as real-time before joining. Not
doing this results in an uncaught exception and a crash.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>