If the system has no working Metal devices, disable the visualization.
The legacy visualization was also too slow for said systems to handle
reasonably anyway, so I guess it's safe to say that they shouldn't have
to handle any visualizers at all. At least have working audio playback,
of course, since that is the primary function of the application. Too
bad that the OpenGL renderers don't work on my scene, it would be nice
to have a fallback there. GL 4.1 crashes on an M1, and both GL 4.1 and
3.2 crash with SIGFPE division by zero error on Intel Macs without Metal
devices. Meh.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Remove the default Metal device option, as it can return nil on systems
where it won't be expected to work.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The frequency mode, apparently the default, doesn't like that the code
was setting the width of the spectrum data to 11 instead of the default
1000. This was causing it to overwrite freed memory when the spectrum
started processing audio.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The OpenGL fallback was causing division by zero errors on Intel Macs
running macOS High Sierra.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apparently, old macOS wants to divide something by the scale size, so
setting it to zero causes division by zero errors? Let's set it to a
really small number instead.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
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>
Adding a cast here silences a warning from passing a long to a function
accepting an int. It doesn't really matter here anyway, as the long in
question is hard coded to initialize to a fixed sample rate. Even when
sample rate configuration is eventually added, this will still be hard
capped to well within the range of 32-bit integers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Metadata logic code should be using this dictionaryWithDictionary method
so that the resulting dictionary is actually immutable, like it claims
to be, rather than simply casting it. Safety coding, all that jazz. Not
really a major issue, just feels right.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Most file formats the player supports may or may not have UTF-8 safe
strings in their metadata. This should not be assumed to be UTF-8, and
when it is assumed, it results in nil NSString objects, which results in
inline initializers crashing due to uncaught exceptions.
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>
On legacy OSes, and legacy GPUs, it should use OpenGL and not Metal,
otherwise there could be horrible performance, or even crashes.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
When the visualization window is not open, it should not continue to run
the scene until the app is quit. Apparently, the windowed mode is really
slow on old Intel machines, too. Full screening it is enough to bodge
the entire system session until the machine is remotely rebooted.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Change the peak sphere positions so they float on top of the bottom or
the bars, instead of clipping into them.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add a dedicated spectrum visualization window, and add the necessary
hooks to start its event timer if playback is already running when it is
first opened.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Enable 8x multisampled anti-aliasing, to improve the appearance of the
spectrum on non-Retina/HiDPI displays. It can't really hurt on HiDPI,
either. Hopefully this won't cause it to use a whole load of GPU
resources, more than is reasonable.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Disable color fringing and motion blurring, which were causing artifacts
with the transparent background.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Since we use a non-default path in the repository to store shared hooks,
it needs to be configured on a freshly cloned repository before it can
be usable.
Yeah, I forgot to follow my own directions before working on the project
for quite some time. The error crept in at the following commit:
2aa3ddd545 - Icon replacement, and team ID
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add options to the Appearance preferences page to allow changing the
spectrum's projection between a 2D-like one and 3D perspective, and add
options to change the bar and peak dot colors.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Introduced a brand new spectrum view based on SceneKit, with a scene
created by @kddlb and then altered by me to add the peak spheres. This
new scene should be lighter on display resources, even though it's fully
3D instead of a vector 2D scene done in Cocoa drawing primitives.
Co-authored-by: Kevin Lopez Brante <kevin@kddlb.cl>
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
FFmpeg processed files may also contain the LAME tag magic of 'Lavf' or
'Lavc', not just 'LAME'. Missed this when I was maintaining the FFmpeg
code that handles this, or at least adding iTunes support to it.
Fixes#250 again.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Update includes turning on system generated icons for all file types,
as well as adding several new file types from VGMStream that I missed
the last time around. Also includes some new fields that Xcode added in.
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>
Apparently, Info.plist, as generated by Xcode, is perfectly fine with
raw apostrophes in the source code, and doesn't require it to be an XML
entity.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Fixed an issue with individual files that reference single subsongs
inadvertently dumping all tracks in the referenced bank to the playlist,
instead of only adding the one bookmark or txtp file. Now it matches the
behavior of foobar2000.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This time, a two-fer. First, ensure that file start seeking still skips
over the Xing/LAME header packet properly. Then, ensure that decoding
the last desired packet of the file does not indicate having decoded
more sample data than desired, which may have caused errors when
resuming playback position on restart and then smoothly transitioning to
the next track.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This is a possible fix for another gap issue I experienced, and may be
exposed by seeking from the start of the file without decoding first.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This error was caused by the necessary fix of the previous commit, only
it caused something completely different. Due to the fact that MP3 is
included in the list of formats supported for embedded CUE Sheets, the
open stage performs a seek to the file start after opening the file,
even if there is no sheet embedded. And the resulting seek was supposed
to be a null operation, since the file was already at the start. But, as
a result, this reset the start skip counter to zero, and because the
offset wasn't backwards, but to the same position, it didn't reset the
skip counter to the start of track delay. So, as a result, start of
track delay wasn't being removed, introducing a gap. Now, this change
bypasses the seek function altogether if seeking would do nothing from
the current playback position. Whew.
Fixes#250 and MP3 gaplessness in general, surprised I didn't notice
this sooner myself, but I guess I didn't bother to verify whether my
change would break anything. Whoops.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
A backwards comparison led to seeking forward doing a full seek up from
the file start, and seeking backwards being a non-functional operation,
so the file would just continue playing as if there were no seek.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The code now requires a variable to be set if Display Lists are to be
skipped by setting display processor interrupt as the bypass code is
supposed to. Also handle unsupported Ucode by calling the low level RSP
emulator instead.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Reverted 7f3da31b45, and reverted a past
commit of some sort. Now adding URLs and opening files from the Open...
option will obey the preferences for playlist adding, including modifier
keys, if used.
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 total frames count in the iTunSMPB header is the encoded length, so
add the start and end padding to it for the decoder implementation,
which expects this variable to contain the total decodable length
including the start and end padding. Fixes gapless decoding of iTunes
files.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This dictionary was replaced with an inline literal declaration, but
this defines an immutable dictionary. Change it to a mutable copy.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Shifting negative numbers to the left is undefined behavior, so replace
with a multiply operation instead.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>