Commit graph

306 commits

Author SHA1 Message Date
Christopher Snowhill
048bc7c30d Converter Node: Change volume scale observer
This should fix an exception being thrown because the observer wasn't
registered, or known to be registered. Only register it when it will be
used, and only unregister it if it was registered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-03 01:56:29 -07:00
Christopher Snowhill
3b4313d844 HDCD: Fix how unsigned audio may be processed
Unsigned will alter the input, so move it like the other integer sample
processors do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-24 14:55:29 -07:00
Christopher Snowhill
a92973c6aa HDCD: Make HDCD extension processing optional
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
And disabled by default, at that. I can't actually hear the difference
of Peak Extension in the Rock track I have that claims to use it. And
Low Level Range Extension is more trouble than it's worth on tracks that
use it by mistake, or maliciously, if the case may be. I may add track
tag level control in the future.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-23 21:44:06 -07:00
Christopher Snowhill
8c019c7302 Bug Fix: Include soxr latency in memory allocation
This should be included, for safety purposes, in case the rounding up to
the nearest multiple of 256 samples doesn't bump the buffer size enough.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:03 -07:00
Christopher Snowhill
2401536e5c Crash Fix: Only selectively register observer
This affects User Defaults, but only has any effect on ChunkLists which
are being used for conversion, and only if they're processing DSD source
material. Thus, the observer should only be added on the one stream that
is converting DSD, and should definitely be removed when the object is
deallocated.

This fixes a serious crash bug that mostly appears to only affect Intel
Macs, and has no major side effects on Apple Silicon that I can tell.
It's a good thing I still own an Intel Mac or two to test on, even if
they are both trapped on older releases of macOS.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-13 19:51:12 -07:00
Christopher Snowhill
a1bbfbe3ac Bug Fix: Track advancing when Rubber Band disabled
Apparently I somehow didn't notice this situation because I still had
Rubber Band enabled, and existing users kept it enabled ever since I
introduced it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-11 14:30:09 -07:00
Christopher Snowhill
2cc7ff9c4a Core Audio: Implement proper fade on seek
Whew, what a mess! And this may pave the way for crossfading.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-10 23:09:03 -07:00
Christopher Snowhill
46aac2fa91 Core Audio: Add a slight fading to operations
Add 10 millisecond fade to seeking, pausing and unpausing, and stopping
on command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 23:22:29 -08:00
Christopher Snowhill
d3f99f8987 Bug Fix: Simplification of chunk duration check
This only needs to check that the chunk is empty, not its exact
duration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 17:28:09 -08:00
Christopher Snowhill
aafe817a1f Bug Fix: Correct playback of DSD formats
DSD formats were buffering incorrectly and terminating way too soon.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 17:28:04 -08:00
Christopher Snowhill
36a2d8efd5 Bug Fix: Restart converter on format change
The converter doesn't just require an output format call, it also
requires this input format change callback to actually signal it to
reopen the converter process with a new format setup.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 05:39:17 -08:00
Christopher Snowhill
25d6f6ea7c Quality of Life: Make buildable with old Xcode
Make the code mostly buildable with Xcode as old as 13.2.1, for debug
testing on Big Sur.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 04:39:59 -08:00
Christopher Snowhill
bb78d49f23 Sound Output: Move DSPs, restructure output buffer
Move the DSPs to the output node, so they don't get closed and reopened
across each file. Also restructure the output handler to buffer a little
on its own, to account for track switch activity.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-05 20:07:38 -08:00
Christopher Snowhill
45352f9261 Bug Fix: Handle compile time warning
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:55 -08:00
Christopher Snowhill
68a146f6b8 Bug Fix: Handle gaplessness for headphone filter
The filter uses a pre-buffer of input audio, so extrapolate from the
actual input to fill the buffer. Fixes clicking on non-zero-crossing
track endings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:50 -08:00
Christopher Snowhill
ea7eff40e0 Bug Fix: Restructure Rubber Band gapless handler
Change how samples are accounted for by the filter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:45 -08:00
Christopher Snowhill
45cb841ec0 Bug Fix: Greatly improve audio buffer handling
Buffers were being treated as empty before they were actually processed,
due to races between the current node's end of stream marker and
actually feeding the output buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:30 -08:00
Christopher Snowhill
462a509c85 Debugging: Implement buffer chain logging code
This optional code, disabled at compile time by default, allows finding
weird issues with the sample decoding chain.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:20 -08:00
Christopher Snowhill
8c97f075cf Bug Fix: Remove observer cleanup
Apparently, this isn't needed, and on two users reporting crashes,
actually causes exceptions to be thrown somewhere.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-01 15:18:21 -08:00
Christopher Snowhill
83ba062010 Seeking: Restart output completely on track seek
This required some minor workarounds to deal with the play time counting
that works toward play count reporting.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-28 17:56:22 -08:00
Christopher Snowhill
00d861efc0 Bug Fix: Unregister observer correctly
Only unregister it if it was actually registered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 14:39:21 -08:00
Christopher Snowhill
bfa9660437 Cleanup: Remove unused code
This is no longer needed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 14:31:58 -08:00
Christopher Snowhill
2be457f395 Bug Fix: Rubber Band should now flush last chunk
There is a race condition with the next Node in the chain and the End of
Stream marker, considering how tiny the buffering is for these DSPs. Set
End of Stream instead after inserting the end of stream flush chunk.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:51 -08:00
Christopher Snowhill
955b90280f Bug Fix: Do not perform cascading reset on DSPs
DSPs should not be performing a cascading reset when resetting just
their own buffers, for example, on init or shutdown of just that one
DSP filter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:47 -08:00
Christopher Snowhill
1909b26671 Bug Fix: Clear counter correctly on reset
This reset was missing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:43 -08:00
Christopher Snowhill
30d9eeec2b Cleanup: Massive code cleanup and reorganization
Cleaned up project settings to current defaults, except for the macOS
deployment version, which is still 10.13. Cleaned up a lot of headers
and such to include with angle braces instead of double quotes. Enabled
build sandbox in a lot of places. Disabled subproject signing in several
places, for libraries and frameworks which will be stripped and signed
when they are copied into place in the final build.

Also, while trying to solve compilation issues, the visualization
controller was reverted to the Objective C implementation, which is
probably faster anyway. Stupid Swift/Objective-C language mixing issues.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 01:15:03 -08:00
Christopher Snowhill
9f6134a588 Bug Fix: Attempt to make seeking more performant
Seeking should clear the buffers completely now, and will be nearly
instant, depending on how fast the input can decode.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-25 18:12:30 -08:00
Christopher Snowhill
375b019972 Bug Fix: Solve outstanding Equalizer bugs
This includes setting and unsetting the equalizer DSP chain objects on
track change and advancing on track playback end, and also bugs with
applying equalizer presets to the band configuration items when the
equalizer is disabled or when playback is stopped.

Fixes #420

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 21:16:46 -08:00
Christopher Snowhill
fa34d469df Bug Fix: Greatly improve seeking operations
Seeking now mutes properly, and will not leave the audio muted across
other operations. Audio output changes should also mute and destroy the
buffers of the input chain, so that the audio resets properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 19:59:13 -08:00
Christopher Snowhill
c02eabcf70 Bug Fix: Fix output volume from seeking
Fixes output volume setting on seek or audio output restart on format
change. Also safeguards these setters so they don't go off if the nodes
aren't actually allocated.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 18:58:55 -08:00
Christopher Snowhill
ff9bd89389 Bug Fix: Clean up input node class definition
Fix some missing items, and add nullability declarations.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-19 15:09:21 -08:00
Christopher Snowhill
023d7e2ba7 Bug Fix: Hopefully fix flickering visualizations
Now buffer twice as much audio as would be requested for a single
visualization PCM/FFT chunk, which should hopefully prevent it from
flickering due to running out of audio because of too low latency.

Now it buffers up to two chunks at the current hard coded visualization
sample rate, which works out to about 186 milliseconds.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:20:02 -08:00
Christopher Snowhill
44b8aa0dd8 Minor Bug Fix: Handle Rubber Band buffer latency
We implement this function to return the current latency buffered,
regardless of how often this function may be called. In practice, it is
only called on track completion, to time the reporting of the next track
display. We also avoid using Rubber Band's latency function, as in most
cases, this function will be called from other threads, and also, it
currently only gets called after Rubber Band has been emptied out, so it
would otherwise calculate zero samples buffered. And thirdly, Rubber
Band's latency function doesn't account for the buffered samples already
removed from it and waiting to be fed out.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:06:30 -08:00
Christopher Snowhill
f251c91f02 Bug Fix: Rubber Band handles end of track gap
The code was polling the input chunk duration after emptying out the
chunk's samples, which resulted in an input duration account sitting at
exactly zero, so the end overrun flush would not be cut short properly,
resulting in gaps between tracks.

Correct the input sum to tabulate before emptying the input chunk, so
output remains properly gapless.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:06:25 -08:00
Christopher Snowhill
dd5be9b117 Bug Fix: Set seek position when resuming paused
And a minor reoder of seek time reset code.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 21:46:46 -08:00
Christopher Snowhill
4face7d631 Audio: Unify playback setup of the converter
This code was being duplicated across three different playback functions
which basically did most of the same things.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 19:58:18 -08:00
Christopher Snowhill
04426d755c Bug Fix: Audio chain should do more error checking
Check all audio chain elements for allocation failures, and also dispose
of all of the previous handles in reverse order, including nulling the
final node handle so the output does not attempt to poll for audio while
the chain is being rebuilt.

Also set up output node to handle the new null finalNode state, and
return an empty chunk to the caller.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 19:58:12 -08:00
Christopher Snowhill
abf77a70d2 Bug Fix: Do not process format change on stop
We should not be processing a potential playback restart when the chain
is being torn down for shutdown.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 01:33:14 -08:00
Christopher Snowhill
923179c4eb Bug Fix: Significantly rework Rubber Band DSP
This should be perfectly safe to use in all situations now. It may have
been unstable due to mishandling return values, or not supporting
requesting more sample data from the library without feeding in more
input first.

Also, still signaling the End of Stream flag on chunk reading should be
correct, as downstream processors only react to it when the buffer runs
empty.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 19:43:24 -08:00
Christopher Snowhill
cdddcaecd8 Audio: Attempt to reduce glitching from seeking
Also applies to how output format changes are handled.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 18:51:36 -08:00
Christopher Snowhill
72a4a1c245 Bug Fix: Downmixer converter should update now
The Downmixer wasn't updating its output format correctly, so it was
prone to outputting the wrong format for a while, which could confuse
the output device and produce garbage output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 18:51:31 -08:00
Christopher Snowhill
ab62de0fa2 Crash Fix: Fix HRTF resampler delay misuse
The delay value should be scaled by the resampling ratio, similar to
how it already is when allocating the impulse buffer. This went
undetected, as it scribbled over other memory without causing immediate
crashes, but instead later heap corruption.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 18:51:27 -08:00
Christopher Snowhill
75441bc5fa Audio: Fix more hangs and resume playback on start
Check for paused processing state in various places, so that startup
playback works properly, and resume playback at seek offset works
properly and doesn't hang the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 22:25:27 -08:00
Christopher Snowhill
ae4c49ea68 Rubber Band DSP: Fix error checking for output
The samples available function returns a signed integer, so it can
apparently return negative on error, and the DSP was incorrectly casting
this to an unsigned type, and thus attempting to buffer an inordinate
number of samples and crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 20:58:17 -08:00
Christopher Snowhill
6470b2627f Audio: Improve buffer signaling
This should stop the deadlocks which were occurring.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 19:58:30 -08:00
Christopher Snowhill
a40fcbca37 Downmix: Move downmix to DSP chain and fix a bug
The downmix filter also had a bug related to the channel configuration
used by the HRTF filter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 14:56:28 -08:00
Christopher Snowhill
aba5b8d120 Audio: Make chunk merging abortable
The merge function should be able to tell when the caller has no audio
left to process, such as on end of stream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 13:51:55 -08:00
Christopher Snowhill
86ce3cf69b Equalizer: Fix to function properly
This was completely broken, oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 13:39:28 -08:00
Christopher Snowhill
fd8b20db86 Audio: Increase buffering before FreeSurround
FreeSurround needs more buffering from its input, so increase buffering
of previous node to 100ms.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 06:35:42 -08:00
Christopher Snowhill
a0e68df0e2 Audio: General fixes and improvements
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 06:35:38 -08:00