Commit graph

32 commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
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
a0e68df0e2 Audio: General fixes and improvements
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 06:35:38 -08:00
Christopher Snowhill
3cc97b5574 Audio: General cleanup and empty chunk checking
Upstream functions which return empty chunks on error do not return nil,
so the caller should check for an empty duration instead.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 01:13:06 -08:00
Christopher Snowhill
8790df1ef0 HRTF DSP: Add gain correction to impulse resampler
Impulses should be gain scaled roughly based on the sample ratio
relative to the original impulses. Lower target sample rate means less
impulses means gain goes up, higher target sample rate means more
impulses so gain goes down. Somewhat simple, seems to work.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 21:08:33 -08:00
Christopher Snowhill
b39882168b HRTF DSP: Support resampling impulses
This prepares the filter to be the same as the rest of the filters, in
that they support flexible sample rates to match the output device.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 20:57:22 -08:00
Christopher Snowhill
d17388ee95 Rubber Band DSP: Make it possible to disable it
And disable it by default in new installations, otherwise leave the
setting alone. The disablement setting is shared with the engine
setting, so the default should not really change anything, except for
new installs.

Also, the time/pitch shifting dialog disables itself and displays an
obvious notice button, which opens the Rubber Band settings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 20:13:53 -08:00
Christopher Snowhill
a82742e689 Audio Processing: Unify sample block merging code
Sample block merging code should not be duplicated across the DSPs that
require it, but instead should be a common function. Also added some
optimizations to the Float32 converter function, to bypass conversion if
the audio format needs no conversion.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 19:01:20 -08:00
Christopher Snowhill
2364a7d469 Rubber Band DSP: Process larger blocks at a time
Attempt to completely fill the input buffer of the Rubber Band library
between each call to the process function, instead of processing in
as small an increment as the source node provides. May reduce processing
power required.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 14:56:44 -08:00
Christopher Snowhill
7994929a80 Audio: Add full timestamp accounting to playback
Audio Chunks now have full timestamp accounting, including DSP playback
speed ratio for the one DSP that can change play ratio, Rubber Band.
Inputs which support looping and actually reporting the absolute play
position now do so.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 14:08:43 -08:00
Christopher Snowhill
b4c8c11218 DSP: Add format change checking to FreeSurround
FreeSurround, like the Equalizer, which attempt to coalesce Audio Chunks
into larger blocks of 4096 samples, must check if the audio format has
changed between blocks, and stop stacking chunks together when a new
format is detected. They will continue processing with less sample data
than expected, as necessary.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 23:02:55 -08:00
Christopher Snowhill
26efcda71a DSP: Move Equalizer processor to DSP node chain
The last of the built-in processors is now in the threaded processing
chain, and all DSPs are marked high priority and with short buffers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 23:01:13 -08:00
Christopher Snowhill
dc0a44067a DSP: Move HRTF filter to DSP class chain
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 21:17:58 -08:00
Christopher Snowhill
7179abe8ef DSP: Move FreeSurround to DSP chain
This will no longer be in the output implementation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 19:43:54 -08:00
Christopher Snowhill
724144accd DSP: Move Rubber Band to its own DSP group
This is a project file structure change only, no code changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 19:42:27 -08:00