Commit graph

652 commits

Author SHA1 Message Date
Christopher Snowhill
c48d55ba9a [Playback] Prevent erroneous file from repeating
Prevent Repeat Single from locking up the player on an unplayable file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 02:20:05 -07:00
Christopher Snowhill
22cd16bb46 [Audio Player] Eliminate an avenue of lockups
Prevent the player from locking up in certain circumstances, by not
locking chainQueue the entire time this function is processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 00:55:41 -07:00
Christopher Snowhill
42b2142ab7 Remove unnecessary files from build and copy steps
Remove a single .inc include from CogAudio build phase, as it's included
but not compiled as Pascal like Xcode thinks. Also remove a bunch of
files from being copied into the resulting .framework and .bundle files
during link stage, as we don't need to distribute that stuff.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 23:58:06 -07:00
Christopher Snowhill
1145bca042 [Equalizer] Fix support for arbitrary channels
The deinterleaved format was being specified incorrectly. Now it asks
for the correct format, which is deinterleaved, and the bytes per frame
or packet sizes are relative to a single channel's buffer, not all
buffers. Oops, that could have been more clear in the documentation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:40:40 -07:00
Christopher Snowhill
7f1c337ee8 [Tag Reading] Moved external cover art reader
Moved external cover art reader to a place where it can be used for any
format, even formats unsupported by Metadata Reader interfaces.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 14:59:47 -07:00
Christopher Snowhill
a32a8718d7 [Plugin Loader] Unregister loader callback
This callback should be unregistered when plugin loading completes,
otherwise we could end up processing bundles loaded by external stuff,
like Audio Units loading for MIDI playback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:31:22 -07:00
Christopher Snowhill
a53a8ecb82 [Audio Output] Fix equalizer support
Equalizer was copying the output of the equalizer repeatedly to the
first output channel, instead of copying each channel correctly. This
had the effect of making the equalizer output adjusted audio to only the
left channel in stereo output, and possibly render the stream sounding
weird.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:11:46 -07:00
Christopher Snowhill
70b01a7cf1 [Plugin Controller] Add Cue sheet safety check
If somehow a plugin doesn't load, skip cuesheet should skip it anyway,
as we don't want any recursive loops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 13:39:06 -07:00
Christopher Snowhill
99f15679a6 [Audio Output] Remove unnecessary variables
These variables weren't being used anyway, so remove them.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 12:42:21 -07:00
Christopher Snowhill
ff56b757e6 [Play Counts] Fix reporting play counts
Play counts are guaranteed to be reported on the correct track now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 23:26:30 -07:00
Christopher Snowhill
2d7c3b51c7 [Audio Output] Restart correct track
When restarting playback on the current track, restart the correct
track, in case restarting near the end of it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:59:23 -07:00
Christopher Snowhill
3b1eefaabb [Play Counts] Track play counts of correct track
Track play counts for the correct track, even on short tracks. Also
correctly track the play count of the last played item in the play queue
which stops with bufferChain set to nil, so the previous iteration was
not tracking it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:57:00 -07:00
Christopher Snowhill
dc02404184 [Metadata Cache] Actually run cleanup thread
Previously, the cleanup thread was not being run. Also, only reset the
metadata deduplication store when the cache is first emptied.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:48 -07:00
Christopher Snowhill
bb11567948 [Audio Output] Change converter back to Obj-C
Change converter source file back from Objective-C++ to Objective-C.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:42 -07:00
Christopher Snowhill
f516658a5e [Equalizer] Prevent crash on stop
Wait for the equalizer to be shut down properly by the main thread
before destroying it. Otherwise, the main thread could crash on stop,
due to accessing the equalizer handle while it's being torn down in the
output thread.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 14:48:02 -07:00
Christopher Snowhill
db181bde4d [Visualization System] Change API a bit
Now the API makes both PCM and FFT data optional, and will do nothing if
neither are requested. Also, it now supports a latency offset in seconds
with floating point precision. The two built-in visualizations currently
request zero larency. Increasing the latency asks for even older samples
while specifying a negative count requests samples from the "future"
relative to what the listener is hearing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 05:40:06 -07:00
Christopher Snowhill
f04761ff42 [Audio Output] Fix for previous commit
This fixes the problem caused by the following commit:

050aaaf852

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:58:10 -07:00
Christopher Snowhill
bc309fe725 [Sandbox] Suggest URLs that are contained in CUEs
Cuesheets can now expose which URLs they contain, which may help with
sandbox path configuration. That is, if the CUE sheets are already
readable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:59:37 -07:00
Christopher Snowhill
378f710cee [Visualization] Resample more audio if present
If upsampling the audio by a significant factor, it may be necessary to
process more than one buffer at a time, rather than lose input.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:59:27 -07:00
Christopher Snowhill
aa3673ed33 [Audio Output] Better handle latency oddities
The visualization buffer now holds up to 45 seconds of loop, and the
latency measurement code now caps this at 30 seconds, and restarts the
output if latency exceeds 30 seconds, such as if a sound output is
reset.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:59:20 -07:00
Christopher Snowhill
c489d7ca91 [Audio Output] Play last track and stop correctly
Play last track up until it actually ends, and stop on command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:43:16 -07:00
Christopher Snowhill
8d10aa7e80 [Audio Output] Fix serious memory leakage
For one thing, the example code I followed was Swift and handled auto
releasing handles in the background, while Objective-C requires manual
handle reference management.

For two, there was no autoreleasepool around the block handling the
input audio chunks, which need to be released as they are pulled out and
disposed of. This also contributed to memory leakage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:00:34 -07:00
Christopher Snowhill
a1a084aabb [Audio Output] Fix serious deadlock issue
There was a serious deadlock issue. Now it is fixed. Whew.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:14:04 -07:00
Christopher Snowhill
cca447ca5e [InputNode] Syntax code fix
This code was misformatted.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:13:57 -07:00
Christopher Snowhill
d79275b285 [Audio Output] Correctly configure WAVE layouts
Correctly configure AVFoundation with the channel layouts supported by
WAVEFORMATEXTENSIBLE speaker position flags, which includes varied
formats supported by FFmpeg and Core Audio inputs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:31 -07:00
Christopher Snowhill
27924e246d [Audio Output] Correctly delay layout updates
Channel layout updates should be delayed when resampling, just like
sample format changes are.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:20 -07:00
Christopher Snowhill
d563617998 [Audio Output] Stop immediately, and fix deadlocks
Stop output when requested, except on natural completion of the last
track in the play queue. Also fix deadlocks with stopping and
restarting.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 19:14:48 -07:00
Christopher Snowhill
0cc084b58b [Audio Output] Properly handle end of playlist
Handle audio on the end of the playlist, flushing playback until all
output stops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:41 -07:00
Christopher Snowhill
858f446597 [Audio Output] Synchronize access, report latency
Report resampler latency properly, and synchronize access to the
resampler objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:33 -07:00
Christopher Snowhill
3a9db65b53 [Visualization] Resample all visualizer audio
Visualizer audio is now resampled to 44100 Hz, for consistency across
the system.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:27 -07:00
Christopher Snowhill
2e45deb8d3 [Audio Output] Resample unsupported sample rates
These rates are too high for Apple's output routines, for some reason.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:19 -07:00
Christopher Snowhill
dccb7f8b47 Replace Core Audio output with Core Media runtime
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>
2022-06-23 23:23:13 -07:00
Christopher Snowhill
2c2a058126 Cog now requires macOS 10.13 as a minimum version
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>
2022-06-23 23:23:07 -07:00
Christopher Snowhill
60523b985a Completely overhaul code signing practices
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>
2022-06-21 22:43:04 -07:00
Christopher Snowhill
2821cb36b5 [Crashlytics] Require asking user consent
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>
2022-06-21 19:03:37 -07:00
Christopher Snowhill
eadac4c033 [Info Plist] Auto format XML escapes
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>
2022-06-21 18:59:57 -07:00
Christopher Snowhill
5d3077963a [Core Audio Output] Guard against nil pointer
Guard against nil refcon in the renderCallback function.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 09:37:29 -07:00
Christopher Snowhill
69f076a293 Update Info.plist
In preparation for submission to the App Store.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 07:08:05 -07:00
Christopher Snowhill
26a20db383 [Sandbox] Update Info.plist generator
Plist generator now emits the output to the temporary folder, which we
have write permission to.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 07:07:42 -07:00
Christopher Snowhill
f948b8ff7e [Cog Decoder Multi] Add dealloc function to close
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>
2022-06-20 22:31:03 -07:00
Christopher Snowhill
2716ca41b0 [Core Audio Output] Refine output function a bit
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>
2022-06-20 22:26:35 -07:00
Christopher Snowhill
ca6a2f41df [Core Audio Output] Move output function block
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>
2022-06-20 22:24:56 -07:00
Christopher Snowhill
6fb991f95e [Sandbox / Sparkle] Update entitlements
Entitlements needed to be updated to allow updating within the sandbox.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-20 17:13:54 -07:00
Christopher Snowhill
1c36869e57 [Audio Threads] Remove unused code
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>
2022-06-18 23:02:24 -07:00
Christopher Snowhill
a2d8e0ec42 [Track Info] Add play count tabulation and display
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>
2022-06-18 23:00:08 -07:00
Christopher Snowhill
4a269f05a1 [Audio Threads] Remove workgroup code
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>
2022-06-18 15:43:40 -07:00
Christopher Snowhill
3156aad9e1 [Audio Threads] Restrict workgroup use to macOS 12
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>
2022-06-17 22:39:00 -07:00
Christopher Snowhill
fa177fe96c [Audio Threads] Make work interval name unique
Work interval names should be unique. Apparently they are deduplicated
based on their names?

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-17 18:04:42 -07:00
Christopher Snowhill
e334d8a017 [Audio Threads] Apply changes to workgroup handler
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>
2022-06-17 18:02:32 -07:00
Christopher Snowhill
dad2dbf236 [Audio Threads] Add extra guard to workgroup exit
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>
2022-06-17 17:00:59 -07:00
Christopher Snowhill
5a6295be1e [Core Audio Output] Fix possible bug in enumerator
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>
2022-06-17 08:24:19 -07:00
Christopher Snowhill
39f4d09c1a Use NSNumber Literals as much as possible
Replaced a bunch of [NSNumber numberWith...] with NSNumber Literals.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-17 06:39:02 -07:00
Christopher Snowhill
95df58dd75 [Crash Reporting] Replace Bugsnag with Crashlytics
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>
2022-06-17 00:11:48 -07:00
Christopher Snowhill
3e01312265 [Audio Formats] Fix handling unsigned formats
This only affects the FFmpeg input, currently.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-16 23:29:52 -07:00
Christopher Snowhill
7044a9a852 [Core Audio Output] Add more event listeners
Sound output format changes should now happen instantaneously instead of
with a delay.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-16 23:28:25 -07:00
Christopher Snowhill
7bc49ccb80 [Event Handler] Fix observers for reused classes
Fix class handling so it cleans up observers if the InputNode is reused.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-16 18:16:09 -07:00
Christopher Snowhill
0997ca2c93 [Core Audio Output] Improve safety on stopping
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>
2022-06-15 22:46:58 -07:00
Christopher Snowhill
e9230a080c [Audio Threads] Change workgroup code for safety
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>
2022-06-15 21:44:03 -07:00
Christopher Snowhill
8db2e41049 [Event Handling] Add context to all observers
Add context field to all observers that support it, in case it's useful.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-15 16:47:43 -07:00
Christopher Snowhill
6825d15f68 [HRIR Filter] Employ impulse cache
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>
2022-06-12 22:21:01 -07:00
Christopher Snowhill
120a93465e [Metadata Handling] Fix dynamic info updates
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>
2022-06-12 19:43:41 -07:00
Christopher Snowhill
90b83f8f51 [Various] Clean up various warnings
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>
2022-06-11 13:42:42 -07:00
Christopher Snowhill
da8288eeee [Converter] Change utility function for safety
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>
2022-06-11 13:39:14 -07:00
Christopher Snowhill
7cac6625d9 [Visualizer] Align memory allocations for DFT
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>
2022-06-11 03:33:42 -07:00
Christopher Snowhill
6c733762d3 [HRIR Filter] Add safety margin for DFT
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>
2022-06-11 03:32:38 -07:00
Christopher Snowhill
040a61e1ed [HRIR Filter] Replace implementation with vDSP
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>
2022-06-11 02:25:40 -07:00
Christopher Snowhill
7b18a9f398 [Visualizer] Add PFFFT implementation for example
The PFFFT implementation is actually slower than Apple's float DFT code.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-11 02:21:17 -07:00
Christopher Snowhill
10f0644407 [Core Audio] Conditionally uninitialize equalizer
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>
2022-06-10 18:43:56 -07:00
Christopher Snowhill
d390febe72 [Core Audio] Remove redundant initialization
These variables will be zero initialized by the class already.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-10 18:42:37 -07:00
Christopher Snowhill
ef2ba385f2 [Audio Threads] Clear workgroup token on exit
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>
2022-06-10 16:42:33 -07:00
Christopher Snowhill
22a41e71d3 [Audio Threads] Add further safety gating on error
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>
2022-06-10 15:20:07 -07:00
Christopher Snowhill
fe82b5ed65 [DSD] Reduce volume level of decimator output
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>
2022-06-10 02:14:04 -07:00
Christopher Snowhill
4537a72275 [DSD] Add pure downsampling path, disabled
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>
2022-06-10 02:13:10 -07:00
Christopher Snowhill
e96a4efa68 [Metadata Loading] Added null pointer guards
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>
2022-06-09 23:18:51 -07:00
Christopher Snowhill
aca29e472b [Bug Reporting] Introduce Bugsnag crash reporting
Crashes will now be collected with an optional comment, and uploaded on
next launch of the app.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-09 18:58:42 -07:00
Christopher Snowhill
6bd0bf1dc5 [Audio Threads] Set realtime priority on old OS
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>
2022-06-09 18:53:58 -07:00
Christopher Snowhill
7813712df3 [Audio Threads] Correctly set real time priority
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>
2022-06-09 18:15:44 -07:00
Christopher Snowhill
91898e9e77 [Audio Threads] Change workgroup system again
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>
2022-06-09 01:38:30 -07:00
Christopher Snowhill
6179b304d0 [Audio Threads] Join output device workgroup
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>
2022-06-09 00:27:55 -07:00
Christopher Snowhill
00ea4562dc Update project files for Xcode 14 recommendations
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>
2022-06-07 18:56:11 -07:00
Christopher Snowhill
c208f60da4 [HRIR Convolver] Rewrite to use PFFFT float
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>
2022-06-06 08:18:33 -07:00
Christopher Snowhill
18af8a06df [Output] [Downmixer] Optimize a bit
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>
2022-06-06 08:16:27 -07:00
Christopher Snowhill
4a0b337936 [Resampler] Change pffft_double project import
Change import from folder reference to group, like I originally
intended.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-05-30 22:31:49 -07:00
Christopher Snowhill
bea896cca5 [Resampler] Switch r8brain back to PFFFT double
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>
2022-05-30 18:24:37 -07:00
Christopher Snowhill
50342891af [Convolver] Normalize HRTF impulse when resampling
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>
2022-05-30 01:39:12 -07:00
Christopher Snowhill
7e0b7f2008 [Resampler] Update r8brain with proper commit
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>
2022-05-30 01:37:11 -07:00
Christopher Snowhill
0cc7e61434 [Resampler] Remove another bad block of code
Oops, I missed some code when fixing it up.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-05-27 04:09:51 -07:00
Christopher Snowhill
f89f1dad5a Change comment to be more correct
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-05-27 04:06:17 -07:00
Christopher Snowhill
527976197a [Resampler] Oops, made an error with multiply
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>
2022-05-27 04:01:49 -07:00
Christopher Snowhill
381e52178c [Resampler] Change FFT to use Accelerate framework
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>
2022-05-27 03:40:14 -07:00
Christopher Snowhill
f7dc6beda1 Plugin utilities: Moved encoding guesser to header
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>
2022-05-24 01:05:43 -07:00
Christopher Snowhill
136200e963 Info.plist generator: Update with default icons
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>
2022-04-21 14:22:43 -07:00
Christopher Snowhill
8cdbc28455 Core Audio Output: Add extra safety checks
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>
2022-03-08 00:00:34 -08:00
Christopher Snowhill
26966c46a2 Cog Audio: Sanitize search paths
Remove references to previously used libraries from search paths.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-06 03:50:01 -08:00
Christopher Snowhill
5622e92899 Resampler: Fix gapless output
The resampler wasn't being given enough room to flush its final output,
so a function was added to determine the current output latency, and
more sample data is requested, allowing the full output flush to occur.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-05 20:40:18 -08:00
Christopher Snowhill
6dccaa4d7f Fixes starting playback on short files
These two changes fix playback issues with either starting in the middle
of the playlist on a really short file terminating immediately instead
of queueing more files (InputNode.m), and issues with starting playback
at all on the end of a playlist on a short file. (OutputCoreAudio.m)

Fixes #246

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-05 15:53:47 -08:00
Christopher Snowhill
7c5cec1eb7 Amend r8bstate definition with extra safety
Just in case anything using the implementation ever needs to request
less sample data than would be returned by the resampler, it should be
able to return a remainder and keep extra remaining samples, if any.
However, the way Cog currently uses it, it would not be likely to run
into this scenario.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-05 15:23:21 -08:00
Christopher Snowhill
ed0f7d81ab Various fixes for R8Brain resampler wrapper
Fixes to the resampler wrapper, such that it will survive some close
encounters with the edge of the buffer, if necessary. Also so it will
obey the buffer size limit for the output buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-04 20:44:36 -08:00
Christopher Snowhill
c9ed4bc678 Rename a variable to be more correct
This rename is more in line with what R8Brain does in its example code.
No actual behavioral changes to the code, however.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-04 14:18:23 -08:00
Christopher Snowhill
777ab28d6a Replaced libsoxr with r8brain free source
Replaced the free SoX resampler with the r8brain resampler source, which
is also free.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-03-04 02:07:38 -08:00
Christopher Snowhill
c8d8e759bc Add autoreleasepool to cache thread
The cache thread should have an autoreleasepool around the release loop,
because it will be freeing Objective C objects periodically.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-26 23:30:18 -08:00
Christopher Snowhill
da4630f4c5 Add a metadata loader cache
Promote the Plugin Controller source file to Objective-C++, and add a
simple data cache that holds on to requests for up to 5 seconds after
their last access, for preventing spammed requests from hitting files
over and over. This is apparently really relevant to the CUESheet reader
and its embedded CUESheet handling, as that tends to reread the same
file over and over as it populates the playlist with tracks. The nested
reader can also lead to repeated reading even on files without CUESheets
embedded.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-26 23:24:32 -08:00
Christopher Snowhill
1dffaae990 Tweak libsoxr for Apple Silicon again
This should improve performance slightly again, as there were some ARM
code paths that weren't being enabled for ARM64.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-26 20:51:30 -08:00
Christopher Snowhill
51e9648865 Improve libsoxr setup
Replace libsoxr dylib with a static library, and also build the two
architectures separately, to allow for platform-specific optimizations
to be employed for both. This also reduces the size of the CogAudio
framework by a few hundred kilobytes, as we eliminate unused code paths
better this way.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-26 01:07:20 -08:00
Christopher Snowhill
9614ec6e98 Add option to quit on natural stop
When the option is enabled, and playback comes to a completion, the
player will quit on its own.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-21 20:55:42 -08:00
Christopher Snowhill
4f5e4eca36 Fix visualization for variable audio block sizes
IN A.D. 2101, WAR WAS BEGINNING. *boom*

Yeah, this was a dumb bug, I didn't realize that AUAudioUnit would just
arbitrarily ignore my configured block size and request a different one.

The AirPods Pro will just request 480 instead of the 512 I ask for, so
let's instead support variable block sizes, and only take up to the last
4096 samples of the chunk fed to the output device.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-16 21:54:55 -08:00
Christopher Snowhill
6d052bc1ac Visualization: Increase temporal resolution
By reducing the window size, we have a more responsive visualization.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 23:22:47 -08:00
Christopher Snowhill
4906c38827 Align all use of Accelerate vDSP functions
vDSP functions expect their input and output pointers to be aligned to
an even four values. Correct this by aligning all pointers. The
allocated buffers used for one parameter should already be aligned
somewhat, but align the incremented positions used on some of them so
that the vDSP functions don't misbehave. Also align the volume scaler
input by doing scalar math until the pointer is aligned prior to calling
vDSP_vsmul. Also, change 16-bit and 32-bit scale to use vsdiv instead of
vsmul with a really small number already divided into one.

Fixes the test vectors that were sent in extrapolating incorrectly due
to their final blocks having uneven sample counts, resulting in
unaligned pointers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 22:53:09 -08:00
Christopher Snowhill
25077277b3 Add bad sample cleaner for debugging
A bad sample scanner and cleaner will point out in the log whenever a
bad sample, such as infinity, or Not a Number, or even huge values over
±2.0, in case some piece of code, or a decoder, or even a bad file, has
taken over the output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 22:48:47 -08:00
Christopher Snowhill
51e8223078 Linear Predictor: Rearrange things somewhat
The original didn't really handle backwards versus forwards differently,
as far as the predictor coefficients should have been, as they probably
should have been reversed for a different direction window.

This didn't fix my problem, though, but did possibly expose something
else to mess with.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 22:41:18 -08:00
Christopher Snowhill
96f2a382ee DSD gaplessness, part 3, mildly pointless
In the rare event that we're somehow playing decimated DSD at full
sample rate instead of resampling, only the start needs to be skipped,
and the end needs the input to the decimator padded to flush it, but
nothing needs to be truncated from the end of the output in that case.
Still, mostly pointless, since next to nobody will be outputting 384 kHz
from their Macs, in any case, much less unprocessed DSD.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 02:29:06 -08:00
Christopher Snowhill
bec01b675a DSD gaplessness, part 2
We should be extrapolating right over top of the DSD decimator latency,
rather than in front of it. Yeah, that'll do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 02:11:53 -08:00
Christopher Snowhill
4b0f6b381f Fix DSD gaplessness handling
DSD files should be properly gapless now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-15 02:03:06 -08:00
Christopher Snowhill
b8a98e301e Metadata loading: Correctly merge over empty tags
Metadata versus properties merging, correctly merge over empty fields if
they are assigned with empty strings or zeroed numbers, instead of only
merging over completely missing fields.

Fixes emailed bug, CUE Sheet metadata reading, primarily.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-14 20:02:18 -08:00
Christopher Snowhill
41efc22096 Equalizer: Bring it back to the quality it had
The quality of the equalizer dialog is now up to par with what we had
before, minus all the crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-13 23:37:58 -08:00
Christopher Snowhill
344ceb173d Visualization: Increased fft size, imported code
Boy, I just be outright stealing code now. But it looks nicer now.

Fixes #234

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-13 12:18:58 -08:00
Christopher Snowhill
cad09b8912 CUE Reader: Fix enumerating sheets and tag reading
The reader should have been skipping the properties of CUE sheets when
reading the referenced data for the inner files.

Fixes #235

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-13 12:18:58 -08:00
Christopher Snowhill
7ef583340d Equalizer: Replace dialog with custom job
New custom equalizer dialog, painstakingly hand assembled.
2022-02-13 11:05:32 -08:00
Christopher Snowhill
417687600b Implement visualization support and a spectrum
Borrowing some DFT code from deadbeef, this implements a simple spectrum
visualization into the main toolbar of the app.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-12 23:04:03 -08:00
Christopher Snowhill
6d09b72c1d Dynamic info now pushes to the correct track
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-12 07:29:02 -08:00
Christopher Snowhill
c39b7ee96a Converter: Smarter, if less portable, endian swap
For big endian sample formats, endianness can be swapped using Clang
specific byte swap functions, which are present in all supported
versions of Xcode.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-12 00:38:08 -08:00
Christopher Snowhill
5f68131437 Converter: One minor change to double to float
Use Accelerate for this, too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-12 00:03:25 -08:00
Christopher Snowhill
6b148fef11 Channel Mixer: Rewrite upmixing, changed HRIR
Simple upmixing algorithms now use Accelerate framework functions
instead of complex loops, and the HRIR filter now supports forcing
stereo output to any channel output configuration that has at least
front stereo speakers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-11 23:51:41 -08:00
Christopher Snowhill
3711999112 Cog Audio: Allocate maximum needed audio memory
The chunk could be any format, up to floating point double samples, and
up to 18 channels.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-11 13:50:26 -08:00
Christopher Snowhill
7f8c19799d Fix a very serious error resampling short files
Files that are so short that they need both pre- and post-extrapolation
at the same time.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-11 07:10:31 -08:00
Christopher Snowhill
0b33fe6dea Don't count output buffering for queue hold
This would count the output duration for every file buffered, rather
than only once.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-11 06:50:58 -08:00
Christopher Snowhill
69c4cb3c16 Minor change to remove unnecessary mutable objects
These are no longer being manipulated, so remove their mutable state.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-11 05:59:44 -08:00
Christopher Snowhill
39dcb88728 FFmpeg input: Support reading metadata
Where TagLib is not being employed, use FFmpeg to read tags where
possible. This allows reading tags from files like IFF. It reads it
through properties, otherwise allowing tag readers to function like
usual.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-10 15:29:13 -08:00
Christopher Snowhill
5ff1f95481 Add decoder open error indicator
When decoder is redirected to the internal silence decoder, show an icon
on the playlist indicating a playback error.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-10 02:15:48 -08:00
Christopher Snowhill
df63726128 Track properties take priority over metadata read from tag readers
This allows inputs to override things with self-read tags and such, such
as ReplayGain tags.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-09 21:26:17 -08:00
Christopher Snowhill
b1a98139cb Cog Audio: Fix generic upmixer mode
This resulted in horrible things, the generic N to N upmixer was leaving
unmapped channels as uninitialized memory. This fixes horrible things
happening for people with interfaces with more channels than the source
file, frequently when the source file is stereo, or if the file is mono
and a center channel is present.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-09 15:16:19 -08:00
Christopher Snowhill
0012d1b17e Implement dynamic metadata reading for streams
Supported by FFmpeg, FLAC, Ogg Vorbis, and Opus.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-09 13:44:50 -08:00
Christopher Snowhill
cdf27e4786 CogDecoderMulti: Reset file even if not seekable
HTTP Reader now supports limited seeking backwards even in streams, so
seek back to file start for repeated file tests, since there are at
least a few inputs that all claim to support things like Ogg containers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-09 13:44:04 -08:00
Christopher Snowhill
7cea254f4c Implement framework for dynamic metadata updates
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-08 21:21:53 -08:00
Christopher Snowhill
0763b28f38 HRIR Filter: Replace deprecated Intel-only code
_mm_malloc and _mm_free are apparently based on intrinsic functions,
and only exist on Intel or older macOS targets. So removing them in
favor of posix_memalign.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-08 00:13:41 -08:00
Christopher Snowhill
f4f4f80f64 Restart playback on device or output format change
Now the output is restarted on the current file at the current position
if the output format has changed. This should resolve the issue finally.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 22:44:56 -08:00
Christopher Snowhill
728c44242c Do not reset output sample rate automatically
This was buggy as hell, and resulted in errors. Now the user should
restart playback if they change output device formats.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 22:02:17 -08:00
Christopher Snowhill
477feaab1d Now properly supports sample format changing
Sample format can now change dynamically at play time, and the player
will resample it as necessary, extrapolating edges between changes to
reduce the potential for gaps.

Currently supported formats for this:

- FLAC
- Ogg Vorbis
- Any format supported by FFmpeg, such as MP3 or AAC

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 19:18:45 -08:00
Christopher Snowhill
91da112e35 Cog Audio: Fix potential hang on stop
The ChunkList wasn't clearing the remover entered flag when the chain
was empty. Now it does, so it will shut down correctly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 15:31:57 -08:00
Christopher Snowhill
08da31f96c Cog Audio: Fix generic downmix to stereo
Code ordering was wrong, it was writing the output samples repeatedly
for each input speaker, now it will only write them once.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 04:17:53 -08:00
Christopher Snowhill
acb1dd75d3 Cog Audio: Fix memory leaks with new buffering
By applying copious amounts of autorelease pools, memory is freed in a
timely manner. Prior to this, buffer objects were freed, but not being
released, and thus accumulating in memory indefinitely, as the original
threads and functions had autorelease pools that scoped the entire
thread, rather than individual function blocks that utilized the new
buffering system. This fixes memory growth caused by playback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 04:06:36 -08:00
Christopher Snowhill
1ef8df675f Cog Audio: Implement support for channel config
This implements the basic output and mixing support for channel config
bits, optionally set by the input plugin.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-07 01:10:05 -08:00
Christopher Snowhill
b0b1446aa7 HRIR Filter: Corrected scale math, fixing volume
The volume should have been twice what it was, because I got this scale
wrong. The correct scale for Accelerate inverse FFT is 1/4 per sample,
not 1/8 like I accidentally misread while rewriting a convolver for the
umpteenth time from scratch.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-06 21:53:42 -08:00
Christopher Snowhill
7bf4c4445d Remove old, now unused code 2022-02-06 21:50:23 -08:00
Christopher Snowhill
85c7073649 Reformat my own source code with clang-format
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-06 21:49:27 -08:00
Christopher Snowhill
62edb39761 Cog Audio: Major rewrite of audio buffering
Rewrite attempt number two. Now using array lists of audio chunks, with
each chunk having its format and optionally losslessness stashed along
with it. This replaces the old virtual ring buffer method. As a result
of this, the HRIR toggle now works instantaneously.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-06 03:08:34 -08:00
Christopher Snowhill
0131f7c925 Revert "Core Audio output: Rewrote major portions"
This reverts commit 637ea4efe1.
2022-02-05 04:14:03 -08:00
Christopher Snowhill
4cdca2f5f8 Converter: Fix DSD gaplessness
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-05 04:03:40 -08:00
Christopher Snowhill
637ea4efe1 Core Audio output: Rewrote major portions
After all this rewriting, down or upmixing the audio is now handled with
the lowest latency possible, meaning that toggling the HRIR option now
takes effect immediately.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-05 03:45:02 -08:00
Christopher Snowhill
3069a81d85 HDCD Decoder: Adjust gain stepping algorithm
This is a fixed point implementation identical to Microsoft's original
algorithm. Or at least I assume it's Microsoft's. It was actually
adapted from hdcd_decode.exe, which was adapted from somewhere else.
It's entirely in fixed point math now, so it's fairly deterministic.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-04 21:52:20 -08:00
Christopher Snowhill
39cc33cac4 Converter: Remove no longer necessary includes
These were only needed when I wasn't using Accelerate framework.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-04 19:53:17 -08:00
Christopher Snowhill
d6760c823a HRIR Filter: Change resampler to use soxr oneshot
This should use the oneshot method, which takes care of flushing for us.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 22:54:27 -08:00
Christopher Snowhill
002be384ff Cog Audio: Terminate queueing when stopping
The end of input queueing, which can go nuts when there are a lot of
short files, should be terminated when the user asks the player to stop.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 22:48:25 -08:00
Christopher Snowhill
074e4115dd sox resampler: Perform post file flush
Flush the resampler when the source file terminates, so that it outputs
delayed samples properly. This fixes gapless decoding of resampled
files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 22:47:11 -08:00
Christopher Snowhill
587be93f21 Cog Audio: Fix runpath search path for libsoxr
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 19:44:48 -08:00
Christopher Snowhill
0e6350116b libsoxr: Fix import path
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 19:28:28 -08:00
Christopher Snowhill
d4990de7f3 Adopt the sox resampler instead of RetroArch
Removing RetroArch code from my project.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 18:55:39 -08:00
Christopher Snowhill
78e960a9e4 Revert "Ring Buffer: Replace virtual buffers"
This reverts commit 476c88973b.
2022-02-01 18:45:12 -08:00
Christopher Snowhill
641f6390c5 HRIR Filter: Quality of life improvements
The memory allocation is now nicer, and only allocates what is needed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 15:28:24 -08:00
Christopher Snowhill
61a30c959c Bundled resources: Use NSBundle interface
These methods should use NSBundle, rather than CF* C functions

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-02-01 14:40:02 -08:00
Christopher Snowhill
808710b881 Volume Control: Fix linear 100% range control
Range is now linear on 100%, like it should be.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-30 00:18:07 -08:00
Christopher Snowhill
476c88973b Ring Buffer: Replace virtual buffers
Replace individual virtual buffers with large _mm_malloc blocks at a
time, then dole out chunks of those buffers as the nodes need them.
Should reduce memory contention a little bit.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-29 21:32:59 -08:00
Christopher Snowhill
9e5a70c9ae Cog Audio: Dealt with a major retain cycle leak
This seals up a major memory leak of the playback state whenever a chain
is released on stop or on manual track change. CogAudioMulti was
retaining the input node due to its listeners, and InputNode was not
releasing the listeners when asked to stop running. This is fixed now.

Fixes #221

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-29 21:31:19 -08:00
Christopher Snowhill
85fd3836c0 Debug logging: Added logging of playback and tags
Added a logging method that indicates starting playback of a given URL,
and added a debug build only logging of every metadata load event.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-29 16:34:43 -08:00
Christopher Snowhill
d239b58ab1 HRIR Filter: Fix 7.0 downmix and WAV files
7.0 downmix was passing parameters to cblas_scopy backwards, and WAV
files report "host" endian, not "native".

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-27 23:02:04 -08:00
Christopher Snowhill
cc2b27d43f Core Audio output: Potential shutdown fix
The thread wait on shutdown had the potential to lock up waiting for the
thread to shut down. Now it should at least spam the semaphores, so that
the thread should progress to shutdown a lot quicker.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-27 00:09:40 -08:00
Christopher Snowhill
bbce6880d7 Core Audio output: Add a quick safety fix
Add a safety fix for pausing and shutting down, so that we don't call
into AUAudioUnit's stopHardware function unless the stream has already
been started by the output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-26 15:42:28 -08:00
Christopher Snowhill
600c447531 Virtual Surround: Further cleanup
Quick changes I missed. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-26 01:03:12 -08:00
Christopher Snowhill
7b5925d7d2 Virtual Surround: General cleanup
This should fix some coding issues, and also fix some potential memory
leaks in the file verifier, assuming it didn't already release the
files it was pulling the stats from.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-26 01:00:28 -08:00
Christopher Snowhill
778ac0699e Virtual Surround: Cleanup properly
The filter wasn't properly freeing its FFT setup state, and also was
unnecessarily null checking the pointers before passing them to the
aligned free function, which already does null checking.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-25 22:06:53 -08:00
Christopher Snowhill
c7c3c82c18 Core Audio output: Change end of file timing
Reduce the timing at which an end of file notification is sent to the
main thread from 16384 bytes to 8192 bytes. This may help with playback
of a lot of really small files, and skipping tracks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-25 21:55:08 -08:00
Christopher Snowhill
708c7dc721 Headphone Virtualization: Implement customization
Implement the ability to configure and select an HRIR preset to use with
the HRIR filter, or remove the preset. It will validate the file's
usefulness before setting it for the player to use.

Also, fixed back center channel filtering for 7.0 format audio.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-01-25 21:30:33 -08:00
Christopher Snowhill
bb029757fd
Headphone Virtualization: Fix an oops
The previous commit was not sound. Now it is.
2022-01-25 17:45:32 -08:00
Christopher Snowhill
e53144acfa Headphone Virtualization: Implement 7ch impulses
This is needed for HeSuVi no-echo impulses, which are only one channel
per input channel, and mapping uses symmetrical mirroring of the input
set to create the surround effect, since there's no side-to-side delay
in these impulses.
2022-01-25 17:23:34 -08:00
Christopher Snowhill
e7b78085ca New feature: Implemented headphone virtualization
This new virtualizer uses the Accelerate framework to process samples.
I've bundled a HeSuVi impulse for now, and will add an option to select
an impulse in the future. It will validate the selection before sending
it to the actual filter, which outright fails if it receives invalid
input. Impulses will be supported in any arbitrary format that Cog
supports, but let's not go too hog wild, it requires HeSuVi 14 channel
presets.
2022-01-25 16:50:42 -08:00
Christopher Snowhill
ec7009f3fc Equalizer: Instances of GraphicEQ AU are now relinquished to the main thread for destruction instead of being destroyed by the Core Audio Output shutdown 2022-01-24 19:49:43 -08:00
Christopher Snowhill
51caf3f4e3 Cog Audio: Don't overfill the output buffer when asked to reset the buffers 2022-01-23 19:53:50 -08:00
Christopher Snowhill
d364d48944 Cog Audio: Change for recursive lock, fixing a deadlock on buffer resets 2022-01-23 19:50:01 -08:00
Christopher Snowhill
494ad84ea7 Cog Audio: Made ring buffer locking mechanism more secure and/or smarter 2022-01-23 19:36:33 -08:00
Christopher Snowhill
502e52d699 Core Audio output: Hopefully stop buffer looping on device stop 2022-01-22 14:37:37 -08:00
Christopher Snowhill
6011982a63 Equalizer: Correctly activate the equalizer when starting playback 2022-01-22 12:59:59 -08:00
Christopher Snowhill
9d1fd08574 HDCD Decoder: Only process lossless tracks 2022-01-21 22:47:11 -08:00
Christopher Snowhill
26e0e0cead HDCD Decoding: Add HDCD indicator 2022-01-20 23:53:45 -08:00
Christopher Snowhill
178b32cbdf Core Audio output: Remove all delayed track end events when buffer reset 2022-01-19 14:54:04 -08:00
Christopher Snowhill
576f1a702a Core Audio output: Hopefully really fix deadlock issue 2022-01-19 14:50:48 -08:00
Christopher Snowhill
16a58e87a0 Core Audio output: Attempt to fix deadlock near track transitions when buffer resets occur 2022-01-19 14:38:48 -08:00
Christopher Snowhill
6f0a737123 Cog Audio: Implement HDCD decoding 2022-01-19 02:08:57 -08:00
Christopher Snowhill
f2feb3bcd7 Equalizer: Fix applying equalizer presets on automatic track change 2022-01-19 01:23:59 -08:00
Christopher Snowhill
31e5cd9337 Core Audio output: Add debugging code for logging output to disk, only enabled at compile time as necessary 2022-01-19 00:41:42 -08:00
Christopher Snowhill
de193b70e2 Converter: Improve extrapolation for resampler, and also pad decimated DSD, even if not resampling it 2022-01-19 00:40:40 -08:00
Christopher Snowhill
684951bdc0 Change a bunch of NSArray declarations to const collection literals 2022-01-18 18:12:57 -08:00
Christopher Snowhill
f9ace87319 Add static container types to Info.plist generator stub 2022-01-18 16:58:31 -08:00
Christopher Snowhill
9085cf18df Core Audio output: Fix crash on playback reaching the end of the playlist 2022-01-18 16:48:37 -08:00
Christopher Snowhill
5c0a510848 Core Audio output: Add various minor changes 2022-01-18 16:43:58 -08:00
Christopher Snowhill
c4c29be35a Output converter: Limit extrapolation to only be trained on twice as many samples as the extrapolation order 2022-01-18 16:43:10 -08:00
Christopher Snowhill
39a5ee8ab7 Utility: Add stubs to regenerate Info.plist with file type associations 2022-01-18 03:07:32 -08:00
Christopher Snowhill
7a0c1d230e Volume control: Make preamp optional, defaulting to a limit of 100% volume 2022-01-17 22:41:26 -08:00
Christopher Snowhill
83ad969d9b Equalizer: Add option for presets to track the music genre tags 2022-01-17 20:43:08 -08:00
Christopher Snowhill
87c771c67c Equalizer: Add option to toggle the equalizer on or off 2022-01-17 01:22:15 -08:00
Christopher Snowhill
c8057e1037 Fix bug in new Core Audio output code 2022-01-16 14:08:17 -08:00
Christopher Snowhill
71b2f7a4f2 Implement graphic equalizer 2022-01-16 07:32:47 -08:00
Christopher Snowhill
c640481c25 Add SIMD optimized volume scaling 2022-01-16 00:46:21 -08:00
Christopher Snowhill
72453ba05a Cog Audio: Converter now rounds up sample counts affected by resamlping ratio 2022-01-15 23:41:31 -08:00
Christopher Snowhill
8eb2b4c4a3 Cog Audio: Finally fix track glitching on lots of tiny tracks 2022-01-15 02:52:35 -08:00
Christopher Snowhill
fbef034903 Cog Audio: Further overhaul output buffering and track queue code 2022-01-15 02:09:26 -08:00
Christopher Snowhill
5ab728b205 Cog Audio: Overhaul output buffering yet again, adding an extra buffer stage between the converter and the output thread 2022-01-14 22:46:41 -08:00
Christopher Snowhill
ccbfc6ec4b Semaphore: Change timedWait to wait in microseconds 2022-01-14 22:43:46 -08:00
Christopher Snowhill
d24a01a637 Implemented basic embedded CueSheet support 2022-01-14 16:46:35 -08:00
Christopher Snowhill
6315377eaf Cog Audio: Fix extrapolator to use signed type for sample delta 2022-01-14 11:37:52 -08:00
Christopher Snowhill
af6677cf34 Cog Audio: Keep track of last resampler quality used so we don't reinitialize when not necessary, and also keep track of DSD decimated sample rate separately, so the input format remains unmodified 2022-01-14 11:18:50 -08:00
Christopher Snowhill
2e164d3fc8 Cog Audio: Reduce glitching on track change by invoking a delegate method that occurs when the track finishes outputting without waiting for it 2022-01-14 11:16:35 -08:00
Christopher Snowhill
3cc5b46a0e Cog Audio: Improve end of track handling 2022-01-14 10:17:41 -08:00
Christopher Snowhill
cb3782d0b1 Cog Audio: Improve ring buffer 2022-01-14 10:17:08 -08:00
Christopher Snowhill
3ce3edde88 Cog Audio: Fix track end extrapolator used by resampler 2022-01-14 07:39:55 -08:00
Christopher Snowhill
748891f285 Cog Audio / WavPack input: Add DSD decimation to converter, and change WavPack input to emit only raw DSD 2022-01-14 06:26:09 -08:00
Christopher Snowhill
903b457a28 Cog Audio: Make it possible to play obscene sample rate files without major failures 2022-01-14 02:00:32 -08:00
Christopher Snowhill
5aa3f7dd0a Cog Audio: Properly support seeking within the file that appears to be playing, even if it has already finished decoding 2022-01-14 00:29:02 -08:00
Christopher Snowhill
083dbbf18b Cog Audio: Also commit synchronization delay on new track playback 2022-01-13 23:54:16 -08:00
Christopher Snowhill
c8d2864862 Cog Audio: Enhance playback queue handler, so it always halts buffering when there are at least 30 seconds worth of buffers filled, possibly spanning multiple files. Also improve the chain reset function so that playlist changes and playback order control reset the queue properly when the queue refill function is currently entered in another thread. 2022-01-13 23:05:32 -08:00
Christopher Snowhill
7cc89c9f92 Cog Audio: Enhance track end extrapolator so it will always have a reasonable amount of buffered data for extrapolation 2022-01-13 23:03:53 -08:00
Christopher Snowhill
e6124335d1 Cog Audio: Change output callback to always retry reading for sample data until the requested buffer is filled, or until the playback either ends or is torn down. This prevents gaps when the preceding ring buffer wraps around. 2022-01-13 23:02:01 -08:00
Christopher Snowhill
92d29e7acf Cog Audio: Now preserves already resampled output when switching output formats 2022-01-13 19:43:18 -08:00
Christopher Snowhill
ee509b6e13 Cog Audio: Remove unnecessary preprocessor macro for RetroArch code 2022-01-13 18:01:12 -08:00
Christopher Snowhill
73348b1616 Cog Audio: Implement play position skip ahead when output format changes, based on how much converter output is being discarded 2022-01-12 23:17:07 -08:00
Christopher Snowhill
52b17bd4d8 Cog Audio: Implement virtual ring buffer function to read buffered bytes count 2022-01-12 23:16:13 -08:00
Christopher Snowhill
d1b519d59d Cog Audio: Only declare end of stream on read when previous node has declared end of stream and the buffer has actually run empty. This prevents the case where the buffer may terminate early due to the read pointer hitting the end of the ring buffer and wrapping. 2022-01-12 23:15:23 -08:00
Christopher Snowhill
ec7ac74fcd Cog Audio: Fix input chain to reset its buffers when seeking properly 2022-01-12 23:13:49 -08:00
Christopher Snowhill
cc134ce293 Cog Audio: Converter node actually pauses when it is being reconfigured, and resets its buffer when the output format is changed 2022-01-12 23:13:00 -08:00
Christopher Snowhill
b0f5a37e85 Cog Audio: Only proceed to the next track when the current track has actually finished 2022-01-12 21:53:58 -08:00
Christopher Snowhill
5fef62dd03 Cog Audio: Implemented device output and input file format changing support 2022-01-12 21:31:22 -08:00
Christopher Snowhill
9feaffc92d Cog Audio: Made RetroArch resampler safer 2022-01-12 18:45:43 -08:00
Christopher Snowhill
8664bacc60 Core Audio output: Correctly terminate output when requested to stop, preventing a case where multiple outputs were draining the playback buffer at once 2022-01-12 16:04:41 -08:00
Christopher Snowhill
2633e713a3 Cog Audio: Remove seek mess from previous commit 2022-01-12 16:03:49 -08:00
Christopher Snowhill
f1d70aaa54 Cog Audio: Add explanatory comment to source code 2022-01-12 03:36:27 -08:00
Christopher Snowhill
84d445cffe Cog Audio: Fix converter so that seeking on startup playback position resume works properly 2022-01-12 03:01:55 -08:00
Christopher Snowhill
16402f9982 RetroArch resampler: Stub out code we don't need, reducing code size 2022-01-12 03:01:55 -08:00
Christopher Snowhill
3b125c0440 Cog Audio: Improve virtual ring buffer class 2022-01-11 22:50:18 -08:00
Christopher Snowhill
a76f3c3476 Cog Audio: Reorder project files 2022-01-11 22:48:50 -08:00
Christopher Snowhill
f8e3b0e1ee Core Audio output: Some more minor changes 2022-01-11 22:06:41 -08:00
Christopher Snowhill
557e0bd399 Core Audio output: Fix so it stops properly 2022-01-11 20:38:17 -08:00
Christopher Snowhill
91c3feac2e Cog Audio converter: Fix handling signed versus unsigned for 8 bit samples 2022-01-11 19:37:47 -08:00
Christopher Snowhill
f44e4e793b Cog Audio converter: Fix end of track flush and extrapolation 2022-01-11 19:37:17 -08:00
Christopher Snowhill
ed882e25cb Cog Audio: Resampler now extrapolates into latency padding for better gapless playback 2022-01-11 18:19:30 -08:00
Christopher Snowhill
7d4841b1c6 Core Audio output: Don't upmix unless output device requests it by default 2022-01-11 18:18:38 -08:00
Christopher Snowhill
ee05fe9e44 Core Audio output: Add sanity checking for supported formats, and support 64 bit float input data, in case anything actually uses that 2022-01-11 17:09:06 -08:00
Christopher Snowhill
4dd46a1b5b Core Audio output: Fix output stopping properly 2022-01-11 07:52:44 -08:00
Christopher Snowhill
72210c67e4 Replaced AudioQueue output with AUAudioUnit 2022-01-11 07:06:40 -08:00
Christopher Snowhill
c4c9a741ef Replaced AudioToolbox converter process with homebrew solution, using the RetroArch sinc resampler 2022-01-11 04:09:19 -08:00
Christopher Snowhill
dfe92ffedc Audio Player: Fix so ReplayGain isn't reset on seek 2021-12-28 21:05:25 -08:00
Christopher Snowhill
841481599e Audio Player: Minor change 2021-12-28 21:04:46 -08:00