Commit graph

129 commits

Author SHA1 Message Date
Christopher Snowhill
713241a94f Major Bug Fix: Volume control works again
Shouldn't have broken this again.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 10:18:13 -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
c89cc1cff4 Bug Fix: Add more guards to sound output block
These guards should prevent the one crash we saw logged.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-05 20:05:53 -08:00
Christopher Snowhill
05e830c681 Bug Fix: Wait for output to shut down first
In case stop function called on another thread, wait for it to complete
first.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-01 15:18:26 -08:00
Christopher Snowhill
bf5e6d85a3 Cleanup: Remove unused variable
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:56 -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
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
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
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
5b8363c9ec Bug Fixes: Fix monotonically increasing timestamps
Fixes timestamps in several cases where they were being processed
incorrectly, which was causing some chunked audio files to mis-report
timestamps into the past or the future, which caused the seekbar to jump
around in an unpredictable way.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 03:27:24 -08:00
Christopher Snowhill
81b7dcfc0c Visualization: Reworked buffering system
Visualization now buffers in the audio output pipeline, and uses a
container system to delay multiple buffer chains from emitting
visualization data over top of each other. This should stabilize
display output significantly, while introducing minimal lag before
DSP configuration changes take effect.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 01:13:15 -08:00
Christopher Snowhill
9346a4edbd Audio: No longer force output sample rate
We were forcing a resampling ratio to match the HRTF filter supplied
with the app, now we resample the HRTF to match the input audio, which
will be resampled to match the output device settings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 20:59:41 -08:00
Christopher Snowhill
7543020291 Cleanup: Whitespace removal
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 19:01:29 -08:00
Christopher Snowhill
9fd393b64e Audio Output: Set higher priority on output thread
It's more like the output monitor thread, since it only monitors output,
rather than actually handing the output callbacks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 19:01:25 -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
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
0e608481d9 Output: Remove pointless scale value
This shouldn't have been applied, the problem with Rubber Band was the
flushing mechanism.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 18:12:51 -08:00
Christopher Snowhill
227ed0dfa3 Rubber Band: Move everything to a DSP class
This class can more flexibly process and emit varying chunk sizes than
the previous code could, solving the problem of wide tempo changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 01:25:26 -08:00
Christopher Snowhill
ad074ec13e Rubber Band: Implement configuration dialog
Now there's a configuration dialog for tweaking the settings
in semi-real time. Everything that can be changed without
restarting is changed without restarting, otherwise the audio
pipeline is reset, which happens quickly enough anyway.

Awaiting translation to Spanish, other languages have been
removed pending their maintainers fixing most of their
problems, which includes me being lazy and AI translating
bits so I could rush updates.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-10 14:37:07 -08:00
Christopher Snowhill
8bc2d3cd38 Audio/HRTF: Make head tracking optional, add reset button
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 15:24:02 -08:00
Christopher Snowhill
9c6915ecb2 Implemented real pitch and time shifting using Rubber Band
I will implement the more complex setup of providing options for
most of the configuration that Rubber Band provides, at a later
date, when I feel like creating a complex configuration dialog
for it, and asking for help translating every option and setting.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-12-09 18:04:34 -08:00
Christopher Snowhill
de43b1b226 Fix FreeSurround being broken by the speed control
It should be deriving its channel count from the file format,
since it's applied before any other filters.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-11-24 15:08:44 -08:00
Christopher Snowhill
6a309a3075 Speed Control: Implement simple speed control
Implements a simple speed control using a resampler
designed for real time changes. A rubberband speed
control will be implemented at a later date.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-09-20 22:25:12 -07:00
Christopher Snowhill
256c99badd Update Copyright year to 2024 manually
Including extending existing starting-2023 dates to ranges.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 05:08:02 -07:00
Christopher Snowhill
1c95771ed0
Hopefully fix memory usage during playback
Shuffle around @autoreleasepool blocks, and also add one
to the audio processing code in the playback callback, so
audio memory is released during playback instead of
accumulating.

Fixes #379

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-11 20:22:39 -07:00
Christopher Snowhill
6b2964328a
Remove redundant track end checker
This is checked inside the audio thread, it isn't needed in the watcher
thread. Remove the second check.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 21:29:54 -07:00
Christopher Snowhill
2102fc1c44
Visualization: Reset buffer on playback stop
Reset the visualization system when stopping playback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 19:35:16 -07:00
Christopher Snowhill
09f7496d9a
Initial implementation of positional audio for macOS Sonoma
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:01:07 -07:00
Christopher Snowhill
fb72db74f8
Stop visualizer feed for stopped playback
A stopped instance of OutputCoreAudio should not continue to feed the
visualization system with stale audio, potentially while another instance
is already starting up and feeding its own audio output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:47 -07:00
Christopher Snowhill
2987857b93
Fix a missing do on a do-while block
This should be looping on the condition, not sure
how the compiler missed this one.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:43 -07:00
Christopher Snowhill
df198110ed
Hopefully fix format change on end of track
This should keep the audio pipeline flowing either way.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:38 -07:00
Christopher Snowhill
a2e4fa17b2
Fix further bugs with output switchover
Change some things I missed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:56:56 -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
a49456f44b
Stash a Core Audio output, kind of glitchy
This output may prove to have lower latency, but the results are too
glitchy to really be usable. Not even visualization latency is handled
correctly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37: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
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
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
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
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
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
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
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
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