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>
Now it allocates audio workgroups per thread, using work slices like the
Apple documentation describes for asynchronous threads.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
On Big Sur or newer, it is possible to join the audio threads to the
same OS workgroup as the audio output device, improving response.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Update all project files with new upgrade version number, and add the
dead code stripping option. Don't touch MASShortcut because it's not my
project.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Replace overlap-add vDSP/Accelerate implementation with a faster PFFFT
overlap-save implementation, using fewer FFT steps as well.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Rewrite some of the output and a lot of the downmixer to use Accelerate
framework instead of dumb for loops.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apparently, PFFFT double is much faster than vDSP, and I didn't even
notice. Thanks to Aleksey Vaneev for testing this properly.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
When resampling the impulse according to the playback rate, it becomes
necessary to normalize the resulting impulse by the inverse of the
sample ratio, as resampling adds more or less loudness by virtue of
interpolating samples.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This will be proper at least unless I get this commit merged upstream.
Squashed the changes to a single commit, and removed extraneous
whitespace that crept into the code.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The function I added only works for non-interleaved real/imaginary pairs
and not the interleaved setup that r8brain expects. Fix that by removing
the multiply implementation and using the original one.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The used fork of r8brain now uses the Accelerate vDSP FFT functions for
resampling, which should provide a slight speedup, or significant for
large sample ratios.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Moved the string encoding guesser/converter to the Plugin.h header, so
it may be accessible from any plugin. I may make it a global member of
something eventually, but a static inline for such a simple function
should be fine for now.
This function facilitates converting arbitrary 8 bit encoded strings to
Unicode NSString objects. It should be used anywhere that UTF-8 is
expected, but not necessarily guaranteed, and where other 8-bit
encodings may also be supplied by a user's files.
Not using this setup for string inputs has already led to failed UTF-8
decoding resulting in nil NSStrings being passed to the inline array or
dictionary initializers, which results in crashes due to uncaught
exceptions.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Update the Info.plist generator to emit file type definitions which use
system generated icons in place of the legacy icons in the app bundle.
Also include the new LSHandlerRank field. And also add a definition for
the scripting definition, which I accidentally added to the Info.plist
manually when I fixed scripting.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add safety check to check if a device is actually alive when enumerating
it, and also add nil pointer checks for the device name before trying to
CFRelease it. Fixes a rare crash on device add/remove cycle, such as
Bluetooth headphones.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>