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>
Another large stack buffer was at play here. Consolidated it into an
existing buffer that can perform double duty here, since neither place
it's used conflicts with each other.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Only unregister the listener if it actually has been registered, and
clear the handle upon doing so.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
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>
The DSPs should not be deinitialized from another thread, possibly while
they are currently processing.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The output implementation has a block size of 4096, so the class
implementation should also use that.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This is the code that actually needs to be added to make it process
audio. This insertion makes the whole app crash when processing audio at
all. Weirdly, simply reverting these two files makes the audio code work
again. I can't explain it.
Also, commenting out CMAudioFormatDescriptionCreate makes it work, too.
There's something weird going on with that function.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This is a working implementation of FreeSurround, but I can't get it to
work in the Cog code base, as the whole project crashes head over heels
if this code is inserted into the output chain.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apparently, Apple's Spatial Audio processor doesn't really support weird
configurations like this. So we need to filter them down to stereo.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This filter replaces the old one, and uses OpenAL Soft presets. Since
there aren't that many of those, I've left off configuration for now,
except to turn it on or off.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The deinterleaved format was being specified incorrectly. Now it asks
for the correct format, which is deinterleaved, and the bytes per frame
or packet sizes are relative to a single channel's buffer, not all
buffers. Oops, that could have been more clear in the documentation.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Equalizer was copying the output of the equalizer repeatedly to the
first output channel, instead of copying each channel correctly. This
had the effect of making the equalizer output adjusted audio to only the
left channel in stereo output, and possibly render the stream sounding
weird.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
If upsampling the audio by a significant factor, it may be necessary to
process more than one buffer at a time, rather than lose input.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The visualization buffer now holds up to 45 seconds of loop, and the
latency measurement code now caps this at 30 seconds, and restarts the
output if latency exceeds 30 seconds, such as if a sound output is
reset.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
For one thing, the example code I followed was Swift and handled auto
releasing handles in the background, while Objective-C requires manual
handle reference management.
For two, there was no autoreleasepool around the block handling the
input audio chunks, which need to be released as they are pulled out and
disposed of. This also contributed to memory leakage.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Correctly configure AVFoundation with the channel layouts supported by
WAVEFORMATEXTENSIBLE speaker position flags, which includes varied
formats supported by FFmpeg and Core Audio inputs.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>