Commit graph

225 commits

Author SHA1 Message Date
Christopher Snowhill
122b6d6a6d
Improve audio buffering situation
Buffer up to 20 seconds per stage, and buffer only up
to 2 seconds before starting the next stage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:51 -07:00
Christopher Snowhill
cfd5b1c6fb
Fix converter after output switchover
This was missing, too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:57:01 -07:00
Christopher Snowhill
7ab2a8305a
Revert to previous low latency output system
This reverts usage of the AVFoundation output to use
the previous lower latency CoreAudio output, and
paves the way for a change I am cooking up soon.

Fixes several issues with playback and seeking latency.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:56:33 -07:00
Christopher Snowhill
eae6c96b5e
Reduce inter-thread buffering a bit
This isn't needed so much now that the output buffers more.

Should reduce the problems of #370

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37:37 -07:00
Christopher Snowhill
2d7a7480d9
Add an option to control halving DSD volume level
And default it to disabled. As was pointed out to me by a user, DSD is
apparently mastered to a level of -6 dB, so double its level on output
by default.

Also reorder all preferences dialog controls so they are instantiated in
display order, which should help screen readers, maybe.

Fixes #368

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-15 16:46:39 -07:00
Christopher Snowhill
323a554832
Fix lossless capability reporting for partial read
When reading partial chunks, and when returning partial data, it is
essential to maintain this lossless chunk status across either whole or
partial chunk reads. Otherwise, the converter chain sees the lossless
flag constantly changing on lossless files, such as PCM or DSD, and
causes the DSD decimator and/or resampler to be torn down and reset
repeatedly, causing glitches in the audio.

The glitch was not, in fact, with the decimator itself, and was
occurring to a degree without it, as it would be restarting the
resampler repeatedly as well.

Fixes #367

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:14:14 -07:00
Christopher Snowhill
ffbc571660
Correct the decimator sample latency
The latency is half of the FIFO, or half the filter size, and each byte
is 8 samples, so return the value accordingly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:11:04 -07:00
Christopher Snowhill
efd1349a59
Add an explanatory comment that got lost
This comment was in the original sample decimator code, I neglected to
include it in my port over to Cog. Doesn't really serve any functional
change, though. It would have clarified that I needed to reduce the gain
level much sooner, though.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:10:10 -07:00
Christopher Snowhill
39459b89cb
Update projects and source in prep for Xcode 15
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:14:45 -07:00
Christopher Snowhill
9822dcc4c0
Audio Player: Only wait for unstopped input
Input thread now signals when it has stopped and is about to return, in
case the input thread returns before the BufferChain dealloc function
would be waiting for it to terminate. Somehow, even though the Semaphore
is being signaled at this point, the BufferChain still ends up waiting
the default of 2.5 seconds for the signal that apparently never comes,
delaying file stoppage. This prevents the wait action entirely. Must
have been some sort of race condition.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:17:45 -08:00
Christopher Snowhill
447a60afd9
Audio Player: Add new method of signaling stop
This new method should cause all stops to default to immediate stoppage,
and only stops that occur after an end of track signal should indicate
to play out the entire buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:14:45 -08:00
Christopher Snowhill
58453a6b7d [Cog Audio] Rename Semaphore.h to CogSemaphore.h
This magically fixes the stupid header maps that were pulling the system
semaphore.h into Swift projects, when they shouldn't have been doing
that in the first place. This is the same reason that the FLAC library
has its assert.h renamed to FLAC_assert.h.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 22:18:40 -07:00
Christopher Snowhill
8db5386053 [Cog Audio] Change a couple of imports
These imports needed to be changed so that Swift bridging didn't import
the system's semaphore.h instead of CogAudio's Semaphore.h, which is a
completely different thing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:38:50 -07:00
Christopher Snowhill
0b8a850086 [Chunk List Converter] Fix repeated initialization
Oops, this compare blunder resulted in DSD decimation breaking every
1024 samples or so, owing to block sizes, and caused ticking sounds as a
result. It would also cause HDCD decoding to break completely.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:05:40 -07:00
Christopher Snowhill
7e03f423c3 [Chunk List Converter] Minor changes
Neither of these two changes is really important, but they do simplify
things, and the division on that one function makes the non-decimating
DSD support actually functional, as the caller expects a specific number
of samples, and that was otherwise octupling the input sample count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:04:25 -07:00
Christopher Snowhill
de9b09251d [Audio Output] Greatly improve sample rate changes
Sample rate changes will now occur on exact sample boundaries, like they
are supposed to. Also, FreeSurround accounts for its output latency.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:18:08 -07:00
Christopher Snowhill
96304dbb17 Significantly reduce stack memory usage
Oops, there were a lot of large local buffers in use here.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 17:28:24 -07:00
Christopher Snowhill
10272ca7a4 [Audio Processing] Increase thread stack size
Apparently, all these new changes with FreeSurround have pushed the
default 512KB thread stack size to the limit. And I'm not even using
stack variables, really, except for maybe the autoreleasepools.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:42:21 -07:00
Christopher Snowhill
38832d9ce9 [Audio Processing] Update for new API
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:38:04 -07:00
Christopher Snowhill
8b418004eb [FreeSurround] Further improvements
Still not working, though.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:47:02 -07:00
Christopher Snowhill
04d394c65c [Audio Processing] Move float32 converter
Move the Float32 converter to a different location, for any future plans
to support decoding audio files to common data for any other purpose.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:45:49 -07:00
Christopher Snowhill
8d8b508d09 [Audio Converter] Minor change for format changes
This should also seal up any potential hole for problems if there's an
audio format change and no audio buffered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:36:31 -07:00
Christopher Snowhill
f8a8a57cf0 [Audio API] Repair the damage to the input chain
The input chain could hang up indefinitely, and MAD decoder didn't
indicate end of file properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:24:21 -07:00
Christopher Snowhill
3c351f6968 [Input API] Change input readAudio method
readAudio now returns an AudioChunk object directly, and all inputs have
been changed to accomodate this. Also, input and converter processing
have been altered to better work with this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:14:47 -07:00
Christopher Snowhill
8bc9738ccb [Downmixer] Only downmix to stereo if not stereo
When downmixing to mono, only downmix to stereo first if the source is
not already stereo.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:08:56 -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
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
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
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
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
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
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
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
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
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
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