The function I added only works for non-interleaved real/imaginary pairs
and not the interleaved setup that r8brain expects. Fix that by removing
the multiply implementation and using the original one.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The used fork of r8brain now uses the Accelerate vDSP FFT functions for
resampling, which should provide a slight speedup, or significant for
large sample ratios.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Moved the string encoding guesser/converter to the Plugin.h header, so
it may be accessible from any plugin. I may make it a global member of
something eventually, but a static inline for such a simple function
should be fine for now.
This function facilitates converting arbitrary 8 bit encoded strings to
Unicode NSString objects. It should be used anywhere that UTF-8 is
expected, but not necessarily guaranteed, and where other 8-bit
encodings may also be supplied by a user's files.
Not using this setup for string inputs has already led to failed UTF-8
decoding resulting in nil NSStrings being passed to the inline array or
dictionary initializers, which results in crashes due to uncaught
exceptions.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Update the Info.plist generator to emit file type definitions which use
system generated icons in place of the legacy icons in the app bundle.
Also include the new LSHandlerRank field. And also add a definition for
the scripting definition, which I accidentally added to the Info.plist
manually when I fixed scripting.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add safety check to check if a device is actually alive when enumerating
it, and also add nil pointer checks for the device name before trying to
CFRelease it. Fixes a rare crash on device add/remove cycle, such as
Bluetooth headphones.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The resampler wasn't being given enough room to flush its final output,
so a function was added to determine the current output latency, and
more sample data is requested, allowing the full output flush to occur.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
These two changes fix playback issues with either starting in the middle
of the playlist on a really short file terminating immediately instead
of queueing more files (InputNode.m), and issues with starting playback
at all on the end of a playlist on a short file. (OutputCoreAudio.m)
Fixes#246
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Just in case anything using the implementation ever needs to request
less sample data than would be returned by the resampler, it should be
able to return a remainder and keep extra remaining samples, if any.
However, the way Cog currently uses it, it would not be likely to run
into this scenario.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Fixes to the resampler wrapper, such that it will survive some close
encounters with the edge of the buffer, if necessary. Also so it will
obey the buffer size limit for the output buffer.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This rename is more in line with what R8Brain does in its example code.
No actual behavioral changes to the code, however.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The cache thread should have an autoreleasepool around the release loop,
because it will be freeing Objective C objects periodically.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Promote the Plugin Controller source file to Objective-C++, and add a
simple data cache that holds on to requests for up to 5 seconds after
their last access, for preventing spammed requests from hitting files
over and over. This is apparently really relevant to the CUESheet reader
and its embedded CUESheet handling, as that tends to reread the same
file over and over as it populates the playlist with tracks. The nested
reader can also lead to repeated reading even on files without CUESheets
embedded.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This should improve performance slightly again, as there were some ARM
code paths that weren't being enabled for ARM64.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Replace libsoxr dylib with a static library, and also build the two
architectures separately, to allow for platform-specific optimizations
to be employed for both. This also reduces the size of the CogAudio
framework by a few hundred kilobytes, as we eliminate unused code paths
better this way.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
When the option is enabled, and playback comes to a completion, the
player will quit on its own.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
IN A.D. 2101, WAR WAS BEGINNING. *boom*
Yeah, this was a dumb bug, I didn't realize that AUAudioUnit would just
arbitrarily ignore my configured block size and request a different one.
The AirPods Pro will just request 480 instead of the 512 I ask for, so
let's instead support variable block sizes, and only take up to the last
4096 samples of the chunk fed to the output device.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
vDSP functions expect their input and output pointers to be aligned to
an even four values. Correct this by aligning all pointers. The
allocated buffers used for one parameter should already be aligned
somewhat, but align the incremented positions used on some of them so
that the vDSP functions don't misbehave. Also align the volume scaler
input by doing scalar math until the pointer is aligned prior to calling
vDSP_vsmul. Also, change 16-bit and 32-bit scale to use vsdiv instead of
vsmul with a really small number already divided into one.
Fixes the test vectors that were sent in extrapolating incorrectly due
to their final blocks having uneven sample counts, resulting in
unaligned pointers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
A bad sample scanner and cleaner will point out in the log whenever a
bad sample, such as infinity, or Not a Number, or even huge values over
±2.0, in case some piece of code, or a decoder, or even a bad file, has
taken over the output.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The original didn't really handle backwards versus forwards differently,
as far as the predictor coefficients should have been, as they probably
should have been reversed for a different direction window.
This didn't fix my problem, though, but did possibly expose something
else to mess with.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
In the rare event that we're somehow playing decimated DSD at full
sample rate instead of resampling, only the start needs to be skipped,
and the end needs the input to the decimator padded to flush it, but
nothing needs to be truncated from the end of the output in that case.
Still, mostly pointless, since next to nobody will be outputting 384 kHz
from their Macs, in any case, much less unprocessed DSD.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
We should be extrapolating right over top of the DSD decimator latency,
rather than in front of it. Yeah, that'll do.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Metadata versus properties merging, correctly merge over empty fields if
they are assigned with empty strings or zeroed numbers, instead of only
merging over completely missing fields.
Fixes emailed bug, CUE Sheet metadata reading, primarily.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The quality of the equalizer dialog is now up to par with what we had
before, minus all the crashes.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The reader should have been skipping the properties of CUE sheets when
reading the referenced data for the inner files.
Fixes#235
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Borrowing some DFT code from deadbeef, this implements a simple spectrum
visualization into the main toolbar of the app.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
For big endian sample formats, endianness can be swapped using Clang
specific byte swap functions, which are present in all supported
versions of Xcode.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Simple upmixing algorithms now use Accelerate framework functions
instead of complex loops, and the HRIR filter now supports forcing
stereo output to any channel output configuration that has at least
front stereo speakers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Where TagLib is not being employed, use FFmpeg to read tags where
possible. This allows reading tags from files like IFF. It reads it
through properties, otherwise allowing tag readers to function like
usual.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
When decoder is redirected to the internal silence decoder, show an icon
on the playlist indicating a playback error.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This resulted in horrible things, the generic N to N upmixer was leaving
unmapped channels as uninitialized memory. This fixes horrible things
happening for people with interfaces with more channels than the source
file, frequently when the source file is stereo, or if the file is mono
and a center channel is present.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
HTTP Reader now supports limited seeking backwards even in streams, so
seek back to file start for repeated file tests, since there are at
least a few inputs that all claim to support things like Ogg containers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
_mm_malloc and _mm_free are apparently based on intrinsic functions,
and only exist on Intel or older macOS targets. So removing them in
favor of posix_memalign.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Now the output is restarted on the current file at the current position
if the output format has changed. This should resolve the issue finally.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>