Commit graph

569 commits

Author SHA1 Message Date
Christopher Snowhill
08539a81e4 Visualization: Do not increment latency on write
The latency should not be incremented when writing sample data to the
buffer, but rather be posted by the output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 01:06:07 -08:00
Christopher Snowhill
b53ebc08fe 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:05:15 -08:00
Christopher Snowhill
3eec6d7700 Audio Chunk: Add interface to copy chunk
This is needed if audio is to be removed from the chunk without altering
the original chunk.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 01:01:52 -08:00
Christopher Snowhill
139ff3a2b8 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:25 -08:00
Christopher Snowhill
de29e33714 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:59 -08:00
Christopher Snowhill
be177617d3 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:59:55 -08:00
Christopher Snowhill
afd2ca2e2a 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:11:05 -08:00
Christopher Snowhill
7101527585 Cleanup: Whitespace removal
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 19:01:10 -08:00
Christopher Snowhill
9589a08724 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:00:52 -08:00
Christopher Snowhill
eaaabafdd2 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 18:54:38 -08:00
Christopher Snowhill
6f6c08dc5b 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:32 -08:00
Christopher Snowhill
ee7aae922d 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:17 -08:00
Christopher Snowhill
92dbe351af 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:04:31 -08:00
Christopher Snowhill
ce2bedf478 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:04:26 -08:00
Christopher Snowhill
8769869aee DSP: Move HRTF filter to DSP class chain
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 23:04:22 -08:00
Christopher Snowhill
d8802bc0da 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 23:04:18 -08:00
Christopher Snowhill
c19de448dc 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 23:04:13 -08:00
Christopher Snowhill
d6b7ed467e 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:06 -08:00
Christopher Snowhill
8f1ef5eb6b Audio: Adjust node buffering behavior a bit
Change one remaining semaphore wait to 500us, and change the buffering
so that it can always overflow the requested duration by one chunk, so
that at least one chunk will always fit in the buffer. This also allows
the DSP nodes to flush at the end of the stream without losing their
output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 18:11:26 -08:00
Christopher Snowhill
108186450f Rubber Band: Handle end of stream flushing better
The end of stream flushing should only request remaining samples once,
as should the rest of the process. The problem with the Rubber Band code
in this case is that it will wrap the remaining samples pointer after it
has been flushed, and emit a really huge number.

Also, add code to try to equalize the samples output with the samples
input, relative to the tempo stretching, as Rubber Band seems to flush
entirely too much data at end of stream, which can create noticeable
gaps in the output. This solves that as well.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 18:09:04 -08:00
Christopher Snowhill
08b991a7c3 Rubberband DSP: Guard non-restart config function
This should be guarded, so that no other thread tries to free the DSP
while it is potentially writing to the Rubber Band instance.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 17:50:07 -08:00
Christopher Snowhill
ec7d936289 DSP: Stylistic change
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 17:45:05 -08:00
Christopher Snowhill
7e5c9c8f7c DSP: Whitespace changes
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 17:44:07 -08:00
Christopher Snowhill
8a468c08ce Cleanup: Remove stale comment from source code
This comment was copied by accident when duplicating the original
Converter Node class for the new DSP base.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 15:10:30 -08:00
Christopher Snowhill
9ef21d8185 DSP: Add thread priority control
DSP threads, such as the Rubber Band processing, and planned moves of
other processing to buffer threads, such as the Equalizer, FreeSurround,
HRTF, and Downmixing for output, because they all have small output
buffers. Since these buffers drain and fill fast, they should be
processed at a high priority. Hopefully, App Store doesn't complain
about the use of these APIs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 15:06:59 -08:00
Christopher Snowhill
9df263e87b Rubber Band: Move default preferences
Move them to the main app instead of an external module.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 01:28:54 -08:00
Christopher Snowhill
4fefdc7ea3 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:23:06 -08:00
Christopher Snowhill
0498eb5f81 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:42:41 -08:00
Christopher Snowhill
37f1be354f Core Audio: Fix API header
Fix a function declaration that was missing its
parameter variable in the header.
2025-02-10 14:40:20 -08:00
Christopher Snowhill
47b4d19f8f Revert "Visualization: Tweak systems a bit"
This reverts commit 88f370ed91.
2025-02-10 14:40:08 -08:00
Christopher Snowhill
88f370ed91 Visualization: Tweak systems a bit
This should improve performance slightly. It's
still recommended to switch off SceneKit to
save CPU usage, or switch of vis entirely.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-01 15:08:25 -08:00
Christopher Snowhill
ae71a6a2bc Audio/HRTF: Make head tracking optional, add reset button
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 15:23:02 -08:00
Christopher Snowhill
cc79342c5b Audio/extrapolator: Fix short prime length
When the input buffer has less samples in it than the LPC order,
it would crash reaching past the ends of the buffer. Now, it will
pad past the correct end of the audio with silence, while still
extrapolating a prime input minimum of the LPC order. Should fix
the last of the outstanding crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 02:20:56 -08:00
Christopher Snowhill
e5eeb987fa 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 00:44:43 -08:00
Christopher Snowhill
95c9f91120 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:07:04 -08:00
Christopher Snowhill
bd457f91e9 Remove unused variable 2024-09-20 22:24:14 -07:00
Christopher Snowhill
27c5e50633 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:23:59 -07:00
Christopher Snowhill
42a7232fda Visualization: Make latency animation smoother
Compensate for latency by incrementing an offset
according to animation frame rate.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-09-20 22:19:36 -07:00
Christopher Snowhill
62ab217c28 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:06:58 -07:00
Christopher Snowhill
681cd18145 Update PluginController.mm
Add missing definitions to the Info.plist template generator.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 03:22:34 -07:00
Christopher Snowhill
0f5f11a5a4
Fix crash on unaligned volume scale
Volume scaling would potentially crash when handling
unaligned blocks of samples, and also handled them
completely wrong. It should be counting up single
samples until the buffer is aligned to a multiple of 16
bytes, and it should not exceed the intended count.

BUG: It was not only counting the unaligned samples
backwards, it was ignoring the real sample count.

Fixes #380

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-11 20:22:17 -07:00
Christopher Snowhill
587b7900b5
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:14 -07:00
Christopher Snowhill
f52de150a7
Processing: Fix missing converter setup function
Oops, I was missing a function necessary for output format changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-04 16:07:20 -07:00
Christopher Snowhill
7634283717
Add a cache shutdown guard
This appears to maybe be necessary as the prior join call doesn't seem to
be doing what it should.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 22:59:23 -07:00
Christopher Snowhill
c4df174ee6
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:28:44 -07:00
Christopher Snowhill
a37026dec2
Reduce audio buffering slightly again
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 19:46:11 -07:00
Christopher Snowhill
8e90da6292 Visualization: Improve latency and buffering appearance
Adjust the buffering so if latency is too low, we fill the rest of
the output with silence instead of peeking at the oldest part
of the buffer. Also increase latency by half a buffer size so
that the requested sample is in the center of the buffer, which
improves the 4096 sample situation with the current low
latency output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 19:34:42 -07:00
Christopher Snowhill
416e77d220 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:32:40 -07:00
Christopher Snowhill
0d682fef37 Initial implementation of positional audio for macOS Sonoma
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 04:59:54 -07:00
Christopher Snowhill
fbde40212c Replace hard coded Pi constant with M_PI
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 04:55:44 -07:00