Compare commits

..

735 commits

Author SHA1 Message Date
Christopher Snowhill
1a0ea3b5d3 Emergency Bug Fix: Fix loading individual tracks
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
And folders of tracks, too! The only thing that worked in 3117 was
playlist files. Hah!

Fixes #436

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-11 05:33:00 -07:00
Christopher Snowhill
7839f661a1 Sentry: Update sentry-cocoa to version 8.50.1
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-10 00:40:24 -07:00
Christopher Snowhill
30db270af3 VGMStream: Updated libvgmstream code base
Updated VGMStream to r1980-277-g72cb4b89

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-09 21:13:34 -07:00
Christopher Snowhill
ab7c0a0afd Track loading: Change file import and sorting
Files are now loaded to unique keys, and containers such as playlists
and CUE sheets maintain their file order. Deduplication now only applies
to top level files and not playlist contents. Sorting applies to top
level files, and playlist or container names, but not their contents.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-09 21:13:28 -07:00
Christopher Snowhill
69533e12c7 VGMStream: Updated libvgmstream code base
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Updated VGMStream to r1980-268-gc32951e9

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-03 01:56:34 -07:00
Christopher Snowhill
048bc7c30d Converter Node: Change volume scale observer
This should fix an exception being thrown because the observer wasn't
registered, or known to be registered. Only register it when it will be
used, and only unregister it if it was registered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-05-03 01:56:29 -07:00
Christopher Snowhill
5753c48245 HDCD: Stop dynamically halving the volume
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Apparently, this doesn't work too well with real HDCD tracks, and causes
all sorts of weird volume issues. Just leave the volume alone, and let
HDCD decoding make tracks louder, possibly, rather than try to halve the
volume automatically on a detector that isn't terribly good.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-24 14:55:33 -07:00
Christopher Snowhill
3b4313d844 HDCD: Fix how unsigned audio may be processed
Unsigned will alter the input, so move it like the other integer sample
processors do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-24 14:55:29 -07:00
Christopher Snowhill
a92973c6aa HDCD: Make HDCD extension processing optional
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
And disabled by default, at that. I can't actually hear the difference
of Peak Extension in the Rock track I have that claims to use it. And
Low Level Range Extension is more trouble than it's worth on tracks that
use it by mistake, or maliciously, if the case may be. I may add track
tag level control in the future.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-23 21:44:06 -07:00
Christopher Snowhill
91c4ed0c98 Maintenance: Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-23 21:44:01 -07:00
Christopher Snowhill
9e889399ec VGMStream: Fix memory leak
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Thanks to upstream VGMStream for fixing this in the Audacious plugin,
which I derived this code from in the first place, which explains the
memory leak getting in.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-20 21:35:27 -07:00
Christopher Snowhill
47a749ace0 VGMStream: Add native support for 24/32 bps int
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-20 21:35:23 -07:00
Christopher Snowhill
4232fb3949 VGMStream: Updated libvgmstream code base
Updated VGMStream to r1980-242-gfccbb05f

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-20 21:35:18 -07:00
Christopher Snowhill
f96cfea2d3 Placeholder commit for Sparkle update
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-20 21:03:54 -07:00
Christopher Snowhill
1cd431019c Updated MASShortcut to fix crashes
I hope this works to fix the crashes from migration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-20 21:00:58 -07:00
Christopher Snowhill
3f0c8d379a Path Suggester: Make font fixed size
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-07 14:14:49 -07:00
Christopher Snowhill
72608ecea0 Path Suggester: Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-04-07 14:14:42 -07:00
Christopher Snowhill
ac26a28f59 Bug Fix: Fix FFmpeg reporting timestamps for DSD
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Raw DSD is counting frames in bytes, not bits/samples, so it needs to be
scaled up when dividing by the raw sample rate.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 20:26:36 -07:00
Christopher Snowhill
a19469325b MIDI: Add unstable configuration for AU players
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
It's regarded as unstable as some plugins randomly decide to overflow
the main thread queue and crash the player on the main thread check, but
only sometimes, and not always.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:51 -07:00
Christopher Snowhill
f4a382c67f Sandbox Security: Disable library validation
Apparently, this was preventing some signed plugins from being loaded
into the process, preventing their use as MIDI plugins. And this may be
needed for future AudioUnit DSP filter support, for third party plugins
there, as well.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:46 -07:00
Christopher Snowhill
25cd57a3cb MIDI: Move sample buffer from stack to class
Move the stack-based buffer, which is rather large, to the player class
instance, where it will be allocated on the heap.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:42 -07:00
Christopher Snowhill
40d9574015 MIDI: Fix Audio Unit player in several ways
Improve rendering functions of Audio Unit player, and also fix looping
for the Audio Unit player, and any other possible future players which
use blocked decoding with timestamped events.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:37 -07:00
Christopher Snowhill
8cfddb875c MIDI: Make BASSMIDI the visible default
Also hide the Apple plugins from settings so they don't get activated
unless there's no SoundFont configured.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:33 -07:00
Christopher Snowhill
54db6c17cb Dependencies: Update BASS and WavPack libraries
BASSMIDI: 2.4.15.3
BASSFLAC: 2.4.5.5
BASSOPUS: 2.4.3
BASSWV: 2.4.7.4

WavPack: 5.8.1

And updated the WavPack plugin to support threaded decoding, using up to
four worker threads, as detected from the host machine's CPU count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 16:18:28 -07:00
Christopher Snowhill
104e959ea2 MIDI: Update BASS docs
This was the version of BASSWV previously bundled.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-28 15:26:22 -07:00
Christopher Snowhill
9a23ff9ff9 Audio Output: Optimize fader function
Now using Accelerate methods to calculate and multiply ramps per channel
and add the remainder if necessary.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-27 17:13:47 -07:00
Christopher Snowhill
6b23590ac8 Play Control: Previous track now also restarts
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
If the current track has played for more than 5 seconds, previous track
now restarts the current track, instead of jumping back to the previous
track.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:18 -07:00
Christopher Snowhill
2282538c42 Bug Fix: Fix inserting empty chunks on track ends
This code did not check the number of samples in a packet before adding
it to the output buffer, which apparently had the potential to cause the
output code to emit up to 512 samples of silence between tracks. This,
as one can guess, is a bad thing, and causes noticeable gapping between
tracks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:13 -07:00
Christopher Snowhill
73951d6fe7 Bug Fix: Fix output logging, switch log method
Output logging, a debugging feature that is only enabled at build time
if I need to chase down some audio mixing or output bug, was not logging
anything at all. Change to use Cocoa file writing methods, and actually
implement the output writer function again.

This code is left disabled 99% of the time anyway, and especially in
release builds. Like the node logging code elsewhere, it has the
potential to be very noisy and consume massive amounts of disk space.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:08 -07:00
Christopher Snowhill
8c019c7302 Bug Fix: Include soxr latency in memory allocation
This should be included, for safety purposes, in case the rounding up to
the nearest multiple of 256 samples doesn't bump the buffer size enough.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:03 -07:00
Christopher Snowhill
f7b2c481e6 Bug Fix: Retry MP3 file a few times before failure
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Give up after 10 tries.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-24 16:05:36 -07:00
Christopher Snowhill
2038a140ed Bug Fix: Fix minimp3 to deal with invalid files
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
If a file can't decode, there should not be a division by zero error.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-24 15:42:39 -07:00
Christopher Snowhill
18d3f76152 Bug Fix: Fix minimp3 streaming support
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
The streaming support was breaking because initial packet detection was
failing due to bit reservoir errors. Instead, detect consecutive sync
frames in the initial read buffer, then attempt to sync to a decodable
frame in the first block of data, otherwise give up.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-24 08:16:47 -07:00
Christopher Snowhill
2237863f08 FFmpeg: Fix HLS, HLS metadata, update FFmpeg
Add missing HLS MIME type: audio/mpegurl

Update FFmpeg to version 7.1.1, carrying the same patches, and one new
patch: Implementing support for HLS ID3 tags changing mid-stream.

We cannot do away with fdk-aac yet, because the USAC codec is missing
features that fdk-aac implements already.

Fixes #428

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-24 06:09:40 -07:00
Christopher Snowhill
ac93ff038e Bug Fix: Fix minimp3 seek position
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
Seek offset is scaled by the number of channels in the file. Oops again.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 20:22:27 -07:00
Christopher Snowhill
184e1f14c9 Bug Fix: Free memory buffers used by minimp3
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
This was being leaked when playing static, seekable files. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 20:04:00 -07:00
Christopher Snowhill
c24d914127 minimp3: Numerous buffering fixes, consolidation
Move minimp3 packet decoder state into the decoder_ex state structure,
instead of using the redundant duplicate structure. Also reduce input
buffer size for streams to 16KiB, and actually use the defined macro in
the header file to declare the streaming buffer size.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 20:03:55 -07:00
Christopher Snowhill
4b0f4a43fd minimp3: Fix seeking behavior
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
Seeking should clear the sample buffer if it contains anything, and non-
seekable files should return an error on an attempt to seek.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 16:18:44 -07:00
Christopher Snowhill
b67b2acd6a VGMStream: Update associated filename extensions
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 16:18:39 -07:00
Christopher Snowhill
90c5833fe9 VGMStream: Considerably rewrite plugin interface
It was about time to rewrite this anyway. Now adapted to the new public
interface API.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 16:18:35 -07:00
Christopher Snowhill
8b3a165d9a Bug Fix: Fixed several code signing issues
There were several issues which broke debug and possibly release
signing, and broke VGMStream in debug situations. Not sure if it was
also broken in release.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 16:18:29 -07:00
Christopher Snowhill
cbaacd35b1 VGMStream: Updated libvgmstream code base
Updated VGMStream to r1980-181-g10093db5

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 16:18:25 -07:00
Christopher Snowhill
9b683a9c56 Bug Fix: Reorder LPC scratch memory for alignment
The double members should be ordered first so they are aligned to an 8
byte boundary. The rest are fine as-is.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 00:05:19 -07:00
Christopher Snowhill
7ff653b48f MP3: Replace MAD with minimp3
libMAD had memory safety issues, possibly with corrupt files. Hopefully,
this will fix the problem.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-23 00:05:11 -07:00
Christopher Snowhill
31281197d4 Code Fix: Change visualizers to only copy FFT data
These two visualization components, SceneKit and Core Graphics based,
only use the FFT data. So now make the request drop the PCM data.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-13 19:51:27 -07:00
Christopher Snowhill
7cb010e337 Code Fix: Add nullability flags to Vis Manager
The Visualization Manager PCM/FFT copy function was already observing
these parameters for null input and only returning output to the ones
which were not null. This just makes it clear that they are both
optional parameters. This is useful for future visualization adventures,
allowing PCM copy without invoking the FFT processing, or requesting FFT
without also having to keep the PCM.

This is mostly only a compile time change, and has no noticeable effect
on the current runtime behavior, as the only consumers of the Visualizer
data currently request both PCM and FFT.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-13 19:51:22 -07:00
Christopher Snowhill
d97b1e788a Sentry: Update sentry-cocoa to version 8.47.0
This release is a bug fix against the Sentry integration from the
upstream project.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-13 19:51:16 -07:00
Christopher Snowhill
2401536e5c Crash Fix: Only selectively register observer
This affects User Defaults, but only has any effect on ChunkLists which
are being used for conversion, and only if they're processing DSD source
material. Thus, the observer should only be added on the one stream that
is converting DSD, and should definitely be removed when the object is
deallocated.

This fixes a serious crash bug that mostly appears to only affect Intel
Macs, and has no major side effects on Apple Silicon that I can tell.
It's a good thing I still own an Intel Mac or two to test on, even if
they are both trapped on older releases of macOS.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-13 19:51:12 -07:00
Christopher Snowhill
a1bbfbe3ac Bug Fix: Track advancing when Rubber Band disabled
Apparently I somehow didn't notice this situation because I still had
Rubber Band enabled, and existing users kept it enabled ever since I
introduced it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-11 14:30:09 -07:00
Christopher Snowhill
2cc7ff9c4a Core Audio: Implement proper fade on seek
Whew, what a mess! And this may pave the way for crossfading.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-10 23:09:03 -07:00
Christopher Snowhill
54c9f30e8a Bug Fix: Don't display notification on seek
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-10 23:08:57 -07:00
Christopher Snowhill
a09907ccd9 Metadata: Move encoding helper to CogAudio
Move this commonly used string decoding helper to the CogAudio framework
and import it in every plugin that uses it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-10 14:55:56 -07:00
Christopher Snowhill
5d73246926 Bug Fix: Handle invalid UTF-8 decoding errors
Apparently, stringWithUTF8String: just returns nil when the encoding is
not UTF-8, rather than throwing an exception.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-10 14:55:51 -07:00
Christopher Snowhill
532d22b9bb App Store: Add encryption attestation
Finally add this to Info.plist properties to save a few seconds on
submissions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:50:35 -07:00
Christopher Snowhill
aee05d5503 Bug Fix: Change how pause stops unseekable files
Change the stop action slightly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:45:01 -07:00
Christopher Snowhill
d4dcf29dd4 Bug Fix: Disable seeking hotkeys when unseekable
Disable the seek forward and backward actions when the current track
doesn't support seeking.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:44:26 -07:00
Christopher Snowhill
90a62821f4 Preferences: Touched by Xcode
Xcode really wants to add focusRingType="none" to everything now upon
opening with the editor, for some reason.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:19:17 -07:00
Christopher Snowhill
f889b34b1b Bug Fix: Add more constraints to general prefs
Add more constraints so the checkboxes are properly spaced again.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:13:18 -07:00
Christopher Snowhill
2733ee95f3 Playlist Loader: Add option to skip playlists
When parsing folders, add option to skip importing playlist files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 23:01:47 -07:00
Christopher Snowhill
2042034868 Bug Fix: Remove missing outlet from preferences
This is a reference to the updates pane that doesn't exist in the App
Store version of Cog.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 22:30:51 -07:00
Christopher Snowhill
0a849fc1d9 FFmpeg: Handle multiple attached pictures properly
Now it handles multiple attached pictures and tries to pick out the one
which may be the front cover picture, or otherwise picks the first one.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 20:06:49 -07:00
Christopher Snowhill
b0fd359388 Crash Fix: Fix a serious bug in previous commit
Fixes commit 9c1c6d7130, where code was
treating a dictionary like an array.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 18:30:34 -07:00
Christopher Snowhill
318cfd71ea Bug Fix: Fix circular bind setter loop in hotkeys
MASShortcut had a potential circular loop in its bindings, let's fix
that right up.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 18:23:39 -07:00
Christopher Snowhill
9c1c6d7130 Bug Fix: Operation blocks should queue inputs
Operation blocks cannot expect their out of scope variables to be
present when the block executes, so design the block operation to pull
inputs from a queue array one at a time, like the rest of the blocks do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 15:05:20 -07:00
Christopher Snowhill
cf77521bb7 Bug Fix: Handle possible null exceptions
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 15:05:15 -07:00
Christopher Snowhill
f8ee7e5e46 Core Audio: Fix pausing glitches
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 14:43:16 -07:00
Christopher Snowhill
e64c279e45 Disable global hotkeys again for macOS < 15.0
Clearly, NSUserDefaults bindings were not really meant to be used in
practice at all, as they do nothing but crash the app.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-09 14:26:07 -07:00
Christopher Snowhill
0de555c2fd Re-enable hotkeys and change preferences storage
Change hotkey storage system, hopefully this will fix the stability
issues that have been plaguing it for a while now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-08 20:24:25 -08:00
Christopher Snowhill
442dfb726b Bug Fix: Disable hotkeys on macOS older than 15.0
Apparently even touching the NSUserDefaults with MASShortcut there is
crash inducing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-08 12:34:38 -08:00
Christopher Snowhill
afeb614481 Bug Fix: Actually perform a fade in
It doesn't fade if we don't advance the sample pointer. Ugh.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-08 00:38:56 -08:00
Christopher Snowhill
63a5239346 Core Audio: Slight change to audio fade in on seek
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-08 00:38:50 -08:00
Christopher Snowhill
0570ebedea Core Audio: Increase fade duration to 125ms
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 23:44:46 -08:00
Christopher Snowhill
1d8803e6f2 Core Audio: Shut off device after fade out
And resume playback before fade in.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 23:44:24 -08:00
Christopher Snowhill
46aac2fa91 Core Audio: Add a slight fading to operations
Add 10 millisecond fade to seeking, pausing and unpausing, and stopping
on command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 23:22:29 -08:00
Christopher Snowhill
ff5a1c6c2c Bug Fix: Prevent hangs when starting paused
This happens when the player is resumed paused, sometimes near the end
of a track.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 20:14:39 -08:00
Christopher Snowhill
d99eda15b5 Bug Fix: Disable hotkeys configuration on macOS<15
MASShortcutView is apparently buggy on older macOS versions. So everyone
there gets hard coded shortcuts and nothing else.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 17:51:17 -08:00
Christopher Snowhill
d3f99f8987 Bug Fix: Simplification of chunk duration check
This only needs to check that the chunk is empty, not its exact
duration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 17:28:09 -08:00
Christopher Snowhill
aafe817a1f Bug Fix: Correct playback of DSD formats
DSD formats were buffering incorrectly and terminating way too soon.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 17:28:04 -08:00
Christopher Snowhill
36a2d8efd5 Bug Fix: Restart converter on format change
The converter doesn't just require an output format call, it also
requires this input format change callback to actually signal it to
reopen the converter process with a new format setup.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 05:39:17 -08:00
Christopher Snowhill
17b8647052 Bug Fix: Ensure robust output format changes
Output format mostly requires stopping and restarting the output device,
and this also prevents us from using the latency function properly,
which apparently always returns 0 for output devices anyway. These
changes also prevent the output callback from hanging when resets occur.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 05:39:12 -08:00
Christopher Snowhill
a3385d1af9 Crash Fix: Change how default shortcuts are stored
It turns out that initializing NSUserDefaultsController like this is a
really bad idea, especially on older versions of macOS. This is probably
also why the equalizer was crashing for people on first activation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 04:40:08 -08:00
Christopher Snowhill
9cc0b8be8d Cleanup: Remove unused code
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 04:40:04 -08:00
Christopher Snowhill
25d6f6ea7c Quality of Life: Make buildable with old Xcode
Make the code mostly buildable with Xcode as old as 13.2.1, for debug
testing on Big Sur.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-07 04:39:59 -08:00
Christopher Snowhill
d7681bda71 Translation: Missing string recently added
Translation provided.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 16:47:16 -08:00
Christopher Snowhill
355169475d Sentry: Replace deprecated SentryUserFeedback use
Replace with newer SentryFeedback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 14:58:12 -08:00
Christopher Snowhill
918aa59920 Sentry: Temporarily disable app hang detection
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 14:51:59 -08:00
Christopher Snowhill
00d42d519e Translation: Properly support this string
Properly support translating the System Default Device name for sound
output devices. Pending a Spanish translation, but in its current state,
it's no different from where it was before this change.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 14:44:20 -08:00
Christopher Snowhill
b41fd74f31 Bug Fix: Default output device changes monitoring
Fix default output device logging, and also the preferences if no
default device happens to be set.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 14:41:28 -08:00
Christopher Snowhill
72bfe1c846 Bug Fix: Latency reporting for high latency output
Fixes visualization latency under virtual machines, at least. Not sure
which local or native systems would be reporting high latency here, but
this should fix them as well.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 13:14:41 -08:00
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
d06ee01a17 Feature: Add seeking hotkeys with defaults
Defaulting to ctrl+command+left/right arrows.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 10:18:08 -08:00
Christopher Snowhill
04db82d0ff Bug Fix: Move default hotkeys to main app startup
Instead of the Preferences plugin.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-06 10:18:03 -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
428ffb1531 Sentry: Bump to version 8.46.0
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-05 20:07:30 -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
4ccd1811b0 Bug Fix: Correct exception handling blocks
These should be catching NSException*, not generic `id`.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-05 20:05:48 -08:00
Christopher Snowhill
45352f9261 Bug Fix: Handle compile time warning
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:55 -08:00
Christopher Snowhill
68a146f6b8 Bug Fix: Handle gaplessness for headphone filter
The filter uses a pre-buffer of input audio, so extrapolate from the
actual input to fill the buffer. Fixes clicking on non-zero-crossing
track endings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:50 -08:00
Christopher Snowhill
ea7eff40e0 Bug Fix: Restructure Rubber Band gapless handler
Change how samples are accounted for by the filter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:46:45 -08:00
Christopher Snowhill
45cb841ec0 Bug Fix: Greatly improve audio buffer handling
Buffers were being treated as empty before they were actually processed,
due to races between the current node's end of stream marker and
actually feeding the output buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:30 -08:00
Christopher Snowhill
e3b48bdc86 Bug Fix: Snap pitch and tempo settings to 1
Pitch and tempo weren't snapping to exactly 1.0 before, as a result of
various things. This fixes that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:25 -08:00
Christopher Snowhill
462a509c85 Debugging: Implement buffer chain logging code
This optional code, disabled at compile time by default, allows finding
weird issues with the sample decoding chain.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:20 -08:00
Christopher Snowhill
c7a160a9e7 Improvement: Hopefully improve tag loading speed
Hopefully this works for most ASCII and UTF-8 tags, and continues to
work for weird tag encodings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:16 -08:00
Christopher Snowhill
2f9d7fe66d Bug Fix: Fix .gitignore file
Oops, the "build" folder reference was incorrect.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-04 00:43:11 -08:00
Christopher Snowhill
cc12da5507
CI: Bump OS and Xcode versions
Bump to macOS 15 and Xcode 16.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-03 18:52:52 -08:00
Christopher Snowhill
b889586708 Playback: Implement Selection Follows Playback
Option to make selection follow the playback, within the lag of the
output buffer, including if Always Stop After Current or Repeat One is
enabled. Allows easily queueing up a list of tracks in Always Stop mode,
then hitting the Play button again to play the next track. Enabled by
default, but always optional to disable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-03 18:37:31 -08:00
Christopher Snowhill
a8902b4ee6 Playback: Implement Always Stop After Current
A new menu option under the Control menu, disabled by default, which
stops playback after the current track completes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-03 18:34:58 -08:00
Christopher Snowhill
5e324927c5 Miscellaneous: File touched by Xcode
Xcode sure does love to tweak the numbers randomly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-03 18:34:51 -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
8c97f075cf Bug Fix: Remove observer cleanup
Apparently, this isn't needed, and on two users reporting crashes,
actually causes exceptions to be thrown somewhere.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-01 15:18:21 -08:00
Christopher Snowhill
83ba062010 Seeking: Restart output completely on track seek
This required some minor workarounds to deal with the play time counting
that works toward play count reporting.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-28 17:56:22 -08:00
Christopher Snowhill
10f8d0c2e1 Bug Fix: Attempt to solve a next track crash
This was attempting to retrieve the NSURL host object, possibly on a
file URL where the two did not match a previous check. Now we only pass
the full scheme/host/path check if both URLs are not file URLs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-28 16:34:26 -08:00
Christopher Snowhill
9fc7c99022 Optimization: Perform container checks in queue
Perform the file container checks in an operation queue, since those are
a major bottleneck at this point, too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 19:05:22 -08:00
Christopher Snowhill
00d861efc0 Bug Fix: Unregister observer correctly
Only unregister it if it was actually registered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 14:39:21 -08:00
Christopher Snowhill
bfa9660437 Cleanup: Remove unused code
This is no longer needed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 14:31:58 -08:00
Christopher Snowhill
24888a669b Bug Fix: Correctly set audio volume on play start
Play start was missing this somehow, after a specific commit removed
some code.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 14:31:53 -08:00
Christopher Snowhill
b05f428cde Feature: Add fractional track length tooltips
Add fractional track length tooltips, for extra verbose info goodness.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:59:06 -08:00
Christopher Snowhill
d5ca037943 Bug Fix: Playlist Loader now correctly sorts items
Playlist Loader was sorting only the non-container tracks, and not the
final track list. Move the sort operation to the end of the processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:59:01 -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
2be457f395 Bug Fix: Rubber Band should now flush last chunk
There is a race condition with the next Node in the chain and the End of
Stream marker, considering how tiny the buffering is for these DSPs. Set
End of Stream instead after inserting the end of stream flush chunk.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:51 -08:00
Christopher Snowhill
955b90280f Bug Fix: Do not perform cascading reset on DSPs
DSPs should not be performing a cascading reset when resetting just
their own buffers, for example, on init or shutdown of just that one
DSP filter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:47 -08:00
Christopher Snowhill
1909b26671 Bug Fix: Clear counter correctly on reset
This reset was missing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-27 00:58:43 -08:00
Christopher Snowhill
fb5193ab62 FFMPEG: Optimize file reader access
Improve handling where FFmpeg may call the provided file reader with
AVSEEK_SIZE repeatedly, when file size is not likely to change between
repeated calls. This prevents repeated seek operations that would
otherwise be required to probe the file size each time.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 21:20:38 -08:00
Christopher Snowhill
6855449550 Sentry: Replace most of old logging, add traces
Add event traces to playlist loading and metadata processing queues.
Unfortunately, most of the old non-error events should not be logged,
because Sentry gets terribly spammy with captureMessage events. They
should only be used for error events, or other uncommon events which
do not already throw exceptions or NSError objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 20:29:04 -08:00
Christopher Snowhill
bde8f23ab1 Sentry: Enable profiling for issue debugging
Enable processor usage profiling for the app to gather information for
potential bottleneck tracking.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 02:37:17 -08:00
Christopher Snowhill
d47a96acaa Bug Fix: Fix CI building again
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 01:23:49 -08:00
Christopher Snowhill
4a0cca22b8 Feature: Replaced Crashlytics with Sentry
Crash logging is now handled by the Sentry service.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-26 01:17: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
375b019972 Bug Fix: Solve outstanding Equalizer bugs
This includes setting and unsetting the equalizer DSP chain objects on
track change and advancing on track playback end, and also bugs with
applying equalizer presets to the band configuration items when the
equalizer is disabled or when playback is stopped.

Fixes #420

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 21:16:46 -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
7c169f9ef1 Bug Fix: Stage seeking operation on main thread
This should not interact with the Audio Player object on a background
thread, but instead the main thread queue.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 19:59:06 -08:00
Christopher Snowhill
c02eabcf70 Bug Fix: Fix output volume from seeking
Fixes output volume setting on seek or audio output restart on format
change. Also safeguards these setters so they don't go off if the nodes
aren't actually allocated.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 18:58:55 -08:00
Christopher Snowhill
c45070138a Bug Fix: Playlist item out of range
This should never happen. But apparently it did.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-23 16:40:52 -08:00
Christopher Snowhill
c1665b6ee3 Crash Fix: Change background event to main thread
Two playback event items were set to queue a playback start to a
background thread, when playback should instead be queued on the main
thread. Fix this in a simple way.

This crash was easily reproducible by skipping through tracks rapidly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-22 04:39:54 -08:00
Christopher Snowhill
e3209e8901 Bug Fix: Play Count data may be missing tags
Sometimes the play count data only includes the filenames, and thus will
fail a query for just the tags. Also, a file query may be stored without
the subsong fragment tag, which will also break the tags.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-20 01:27:16 -08:00
Christopher Snowhill
ff9bd89389 Bug Fix: Clean up input node class definition
Fix some missing items, and add nullability declarations.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-19 15:09:21 -08:00
Christopher Snowhill
e49ba8e3e0 Bug Fix: Crash fix sorting by several fields
Play Count sorting was entirely missing, and sample rate and bits per
sample sorting caused exceptions due to the capitalization of the fields
versus the column identifiers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-19 15:09:16 -08:00
Christopher Snowhill
169c798bef Bug Fix: Hopefully fix pasting a list of paths
This should hopefully fix pasting from a list of file URLs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-19 15:09:10 -08:00
Christopher Snowhill
122757b42a TagLib: Fix framework Info.plist again
The TagLib framework build process leaves several
key fields empty. This breaks App Store submission.

Fix it again. Dang.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 19:19:30 -08:00
Christopher Snowhill
0f1be5939d VGMStream: Clean up FFmpeg code somewhat
Remove deprecated functions, make use of free functions that clear the
pointers before returning, etc.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 18:33:29 -08:00
Christopher Snowhill
212ef0ffdf FFmpeg: Clean up code somewhat
Remove deprecated functions, make use of free functions that clear the
pointers before returning, etc.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 18:33:25 -08:00
Christopher Snowhill
1c92c56d75 Bug Fix: Adding tracks to playlist while in search
When adding tracks to the playlist, clear the search filter first, so
the playlist doesn't become all jumbled, or so we don't overflow the
playlist indexes.

Also add some bug fixes for reversing the arranged to disarranged index
lists, so if an arranged index is past the end of the arranged list, as
is the case for appending, we shift the indexes forward past the end of
the diarranged object list.

Extra exception handling was added as well, so these things will only
cause a failure to add playlist items at worst, instead of crashing the
player entirely.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 16:06:16 -08:00
Christopher Snowhill
2e884b9e85 TagLib: Implement preliminary writer class
This is not currently being used anywhere, but may function eventually.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 04:25:36 -08:00
Christopher Snowhill
7e23e80b24 TagLib: Update metadata readers
Update the readers to support the newly added tag fields, and also read
the supported format list from the library itself.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 04:25:30 -08:00
Christopher Snowhill
65e2da2d9e TagLib: Implement new field support
Implement the new fields into TagLib, pending contribution to upstream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 04:25:24 -08:00
Christopher Snowhill
023d7e2ba7 Bug Fix: Hopefully fix flickering visualizations
Now buffer twice as much audio as would be requested for a single
visualization PCM/FFT chunk, which should hopefully prevent it from
flickering due to running out of audio because of too low latency.

Now it buffers up to two chunks at the current hard coded visualization
sample rate, which works out to about 186 milliseconds.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:20:02 -08:00
Christopher Snowhill
44b8aa0dd8 Minor Bug Fix: Handle Rubber Band buffer latency
We implement this function to return the current latency buffered,
regardless of how often this function may be called. In practice, it is
only called on track completion, to time the reporting of the next track
display. We also avoid using Rubber Band's latency function, as in most
cases, this function will be called from other threads, and also, it
currently only gets called after Rubber Band has been emptied out, so it
would otherwise calculate zero samples buffered. And thirdly, Rubber
Band's latency function doesn't account for the buffered samples already
removed from it and waiting to be fed out.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:06:30 -08:00
Christopher Snowhill
f251c91f02 Bug Fix: Rubber Band handles end of track gap
The code was polling the input chunk duration after emptying out the
chunk's samples, which resulted in an input duration account sitting at
exactly zero, so the end overrun flush would not be cut short properly,
resulting in gaps between tracks.

Correct the input sum to tabulate before emptying the input chunk, so
output remains properly gapless.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-16 14:06:25 -08:00
Christopher Snowhill
dd5be9b117 Bug Fix: Set seek position when resuming paused
And a minor reoder of seek time reset code.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 21:46:46 -08:00
Christopher Snowhill
b8698ea125 Bug Fix: Rework playlist setup again
In case playlist setup is reset or not, move the reset above the menu
setup code, so the menu is set up correctly if a reset occurs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 20:23:42 -08:00
Christopher Snowhill
f239784bf2 Bug Fix: Change how bad playlist setup is handled
Reset to defaults if no columns are visible. Also log this situation in
Firebase events, in case it becomes relevant.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 20:10:09 -08:00
Christopher Snowhill
4face7d631 Audio: Unify playback setup of the converter
This code was being duplicated across three different playback functions
which basically did most of the same things.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 19:58:18 -08:00
Christopher Snowhill
04426d755c Bug Fix: Audio chain should do more error checking
Check all audio chain elements for allocation failures, and also dispose
of all of the previous handles in reverse order, including nulling the
final node handle so the output does not attempt to poll for audio while
the chain is being rebuilt.

Also set up output node to handle the new null finalNode state, and
return an empty chunk to the caller.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 19:58:12 -08:00
Christopher Snowhill
931da40b4d Bug Fix: Safeguard play count updates
Play Count cannot be updated for tracks which have been deleted before
the update was added to them. This was another cause of a rare crash.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 17:08:10 -08:00
Christopher Snowhill
0d289e47ab Bug Fix: Add safety checks to playlist columns
Playlist column setup needed a couple of safety checks to prevent
crashes from happening.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 14:09:35 -08:00
Christopher Snowhill
abf77a70d2 Bug Fix: Do not process format change on stop
We should not be processing a potential playback restart when the chain
is being torn down for shutdown.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-15 01:33:14 -08:00
Christopher Snowhill
923179c4eb Bug Fix: Significantly rework Rubber Band DSP
This should be perfectly safe to use in all situations now. It may have
been unstable due to mishandling return values, or not supporting
requesting more sample data from the library without feeding in more
input first.

Also, still signaling the End of Stream flag on chunk reading should be
correct, as downstream processors only react to it when the buffer runs
empty.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 19:43:24 -08:00
Christopher Snowhill
abd11ebc3b Opus: Boost priority of libopusfile decoder
This should take priority over the Core Audio and FFmpeg decoders.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 19:07:48 -08:00
Christopher Snowhill
632e53510c TagLib: Re-enable some file types
These may be handled by the Core Audio input, which does not read tags
on its own.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 19:04:14 -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
72a4a1c245 Bug Fix: Downmixer converter should update now
The Downmixer wasn't updating its output format correctly, so it was
prone to outputting the wrong format for a while, which could confuse
the output device and produce garbage output.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 18:51:31 -08:00
Christopher Snowhill
ab62de0fa2 Crash Fix: Fix HRTF resampler delay misuse
The delay value should be scaled by the resampling ratio, similar to
how it already is when allocating the impulse buffer. This went
undetected, as it scribbled over other memory without causing immediate
crashes, but instead later heap corruption.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-14 18:51:27 -08:00
Christopher Snowhill
75441bc5fa Audio: Fix more hangs and resume playback on start
Check for paused processing state in various places, so that startup
playback works properly, and resume playback at seek offset works
properly and doesn't hang the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 22:25:27 -08:00
Christopher Snowhill
ae4c49ea68 Rubber Band DSP: Fix error checking for output
The samples available function returns a signed integer, so it can
apparently return negative on error, and the DSP was incorrectly casting
this to an unsigned type, and thus attempting to buffer an inordinate
number of samples and crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 20:58:17 -08:00
Christopher Snowhill
146dae216a Visualization: Optimize Swift code handling arrays
This looks a lot better than some ruddy for-loops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 19:58:34 -08:00
Christopher Snowhill
6470b2627f Audio: Improve buffer signaling
This should stop the deadlocks which were occurring.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 19:58:30 -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
aba5b8d120 Audio: Make chunk merging abortable
The merge function should be able to tell when the caller has no audio
left to process, such as on end of stream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 13:51:55 -08:00
Christopher Snowhill
86ce3cf69b Equalizer: Fix to function properly
This was completely broken, oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 13:39:28 -08:00
Christopher Snowhill
fd8b20db86 Audio: Increase buffering before FreeSurround
FreeSurround needs more buffering from its input, so increase buffering
of previous node to 100ms.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 06:35:42 -08:00
Christopher Snowhill
a0e68df0e2 Audio: General fixes and improvements
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 06:35:38 -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
d2284df683 FFmpeg Input: Fix stream timestamps
Stream timestamps were correctly being converted from the monotonically
increasing frame count, but the AudioChunk parameter was being set from
the frame count rather than the converted seconds count.

Fixes #418

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 03:27:11 -08:00
Christopher Snowhill
3ed6e8a6b9 Audio Node: Revert timedWait usage
Timed wait for 500us is kind of stupid and makes the threads wake up way
too much, and use way more CPU time. Reduce this, as the semaphores are
signaled appropriately, and the waiter should not wake up constantly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 02:23:52 -08:00
Christopher Snowhill
d9a08914df Visualization: Clean up Swift code a bit
Some of this is handled in simpler ways now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-13 02:09:17 -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
9701bd5421 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:13:10 -08:00
Christopher Snowhill
3cc97b5574 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:13:06 -08:00
Christopher Snowhill
a78933ca80 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:13:03 -08:00
Christopher Snowhill
8790df1ef0 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:33 -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
b39882168b 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:57:22 -08:00
Christopher Snowhill
d17388ee95 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:13:53 -08:00
Christopher Snowhill
b913d423a2 Crashlytics: Add consent preferences defaults
These should have been defined already, but now they're the safe
defaults that should spring the dialog on startup, and doesn't grant
consent by default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-12 20:11:22 -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
a82742e689 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 19:01:20 -08:00
Christopher Snowhill
2364a7d469 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:44 -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
1e1ee2fbe2 Bug Fix: Fix resume playback on startup
In case multiple playlist entries are left marked as "current" in the
playlist database, resume playback on the first one, and unmark all the
rest of them.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 23:04:01 -08:00
Christopher Snowhill
b4c8c11218 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:02:55 -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
724144accd 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 19:42:27 -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
98bac743df 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:12:46 -08:00
Christopher Snowhill
cddfc3d1db 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:12:41 -08:00
Christopher Snowhill
cb8d873b5b 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 18:12:35 -08:00
Christopher Snowhill
9b3487b6e0 DSP: Stylistic change
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 18:12:30 -08:00
Christopher Snowhill
4890ee67a6 DSP: Whitespace changes
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 18:12:26 -08:00
Christopher Snowhill
9e82e2737e 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:42 -08:00
Christopher Snowhill
7d803a0211 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:10:38 -08:00
Christopher Snowhill
d6923781ef Preferences: Fix merge error
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 13:57:19 -08:00
d8d3265016 Changed term in Spanish translation
Yes, it's mostly used untranslated now...
2025-02-11 09:48:32 -03:00
Christopher Snowhill
7fc6361d6c Rubber Band: Fix preferences disabling items
The items not applicable to Finer / R3 engine were not being disabled
properly. Change the dialog to use a transformer to disable them on the
preferences value instead of coding it, since the code didn't seem to
work.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-11 01:28:42 -08:00
Christopher Snowhill
266da8cc07 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:27:28 -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
48d89d4496 Spanish translation for Rubber Band settings, and
for rubber band icon credits.
2025-02-10 20:07:21 -03:00
Christopher Snowhill
6f6773da09 Fix up team identifiers again
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-10 14:49:00 -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
e4b70f53ae Core Audio: Fix API header
Fix a function declaration that was missing its
parameter variable in the header.
2025-02-10 14:33:28 -08:00
Christopher Snowhill
5392a5fa91 Revert "Visualization: Tweak systems a bit"
This reverts commit 6c24ad8244.
2025-02-10 14:31:22 -08:00
Christopher Snowhill
591f3ceb18 Updated VGMStream to r1980-95-g551c0787
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-10 14:30:28 -08:00
Christopher Snowhill
6e53cebf5c Remove unmaintained translations
The Polish, Russian, and Turkish translations have
no active maintainers, so I was stupidly relying on
AI translation to fill in the newer things. These
translations will sit mostly idle until I get active
maintainers for them.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-10 14:12:42 -08:00
Christopher Snowhill
0b98c0ac98 Placeholder commit for Sparkle update
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-06 20:59:59 -08:00
Christopher Snowhill
6c24ad8244 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:56 -08:00
Christopher Snowhill
170fb06a62 Updated credits file and Patron list
Been a while since I did this. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-01 15:08:50 -08:00
Christopher Snowhill
f4cfad370d TagLib: Fix up project file
Gah, how in heck did Xcode end up inserting an absolute
path? Fix that, and some other leftovers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 02:18:33 -08:00
Christopher Snowhill
dc81605343 TagLib: Fix framework Info.plist
The TagLib framework build process leaves several
key fields empty. This breaks App Store submission.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 01:45:41 -08:00
Christopher Snowhill
994d0e328e SID: Add exception handling
Exception handling was quite missing from this code
as well. Let's fix that too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 01:17:56 -08:00
Christopher Snowhill
ffa46ae2d0 OpenMPT: Update exception handling
Make exception handling more robust and thorough. Never
know what may happen, make sure to handle most cases.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 01:17:49 -08:00
Christopher Snowhill
cd95cd68f8 MIDI: Add exception handling
Both the midi_processing and the various players may
throw exceptions, so we should check for these too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 01:17:44 -08:00
Christopher Snowhill
d835c252fa Highly Complete: Add exception handling for NCSF
SSEQPlayer throws exceptions, there should be exception
handling to catch them and fail gracefully.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-30 01:17:39 -08:00
Christopher Snowhill
7777e50f03 TagLib: Add exception handling
The TagLib C++ code was missing generic try/catch handling
which could result in any generic errors throwing straight
to a full crash. Add exception handling and logging, which
will fix a logged crash regardless of whether the tags are
read correctly or not by the newer TagLib version.

Fixes #415

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-29 23:57:36 -08:00
Christopher Snowhill
b0414f4399 TagLib: Replace bundled copy with upstream 2.0.2
Include a Framework build, unmodified, RelWithDbgInfo.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-29 23:42:31 -08:00
Christopher Snowhill
a873441484 Updated VGMStream to r1980-54-g35c8283f
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-26 01:17:55 -08:00
Christopher Snowhill
dd4a0b7af3 Playlist View: Save column settings differently
You will need to reset your settings after this, but then it should
stay put for the indefinite future.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-26 01:17:47 -08:00
cfa4e078ea
Update bug_report.md 2025-01-20 19:18:40 -03:00
Christopher Snowhill
b0368a7010 Visualization: Fix race condition on first launch crashing
Due to a race condition with the visualization control racing with
the Crashlytics consent dialog, it was possible that the repaint
function would be called before the control was fully initialized,
which would cause the visualization drawing code to crash due to
division by zero error.

The fix is two-fold: First guards were added to the borrowed
code so that the draw functions won't run if they would later
divide by zero on an uninitialized width property. Secondly, the
top level visualization windows added a startup variable guard
so their drawing code will return immediately if setup has not
completed yet.

Note that this bug was only just noticed in a recent App Store
submission, but was unrelated to the recent commits to the code
base, and could have triggered much earlier in the development
cycle. Strangely, it did not.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-15 17:43:03 -08:00
Christopher Snowhill
458d0a3824 Playlist: Added play count column
It should also be possible to sort by the column, ascending or
descending. This also necessitated adding playlist row refreshing
for play count updates.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-14 23:38:22 -08:00
Christopher Snowhill
838d5ca9f7 Highly Complete: Fix crash on paths containing URL escapes
In the event of local paths containing not just UTF-8 characters,
but also un-decoded URL percent sequences, which will end up double
encoded in the player, code which reverses percent encoding should
later re-apply it.

Apparently, this whole time, since the last code overhaul, the
URL encoding was being stripped, then the file opener was converting
these paths back into URLs without re-encoding, which didn't break
until someone played an album in a folder containing a partially
decoded UTF-8 sequence. Thanks, Zophar's Domain, and whoever ripped
the Golden Sun GSF set for finding this bug!

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-14 21:25:52 -08:00
Christopher Snowhill
7e98a0398b Updated libOpenMPT to version 0.7.13
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-10 14:38:44 -08:00
Christopher Snowhill
e400fafa5d Dependencies: Updated mpg123 to 1.32.10
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-10 14:37:59 -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
68c334d96e Updated VGMStream to r1980-0-ged9a7202
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 02:31:11 -08:00
Christopher Snowhill
9f07f04ed6 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:18:35 -08:00
Christopher Snowhill
0707c4bb71 Notification: Fix album date assignment
The NSCalendar assignment should have a placeholder month and day
of January 1st, instead of the invalid month/day of 0/0. Also,
even if this somehow fails, don't attempt to assign it if it
returns nil.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 01:28:07 -08:00
Christopher Snowhill
75ef35efa6 FileTree: Fix handling of metadata with multiple values
Goody, my metadata formatting comes back to bite me.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-03 01:19:24 -08:00
Christopher Snowhill
d89c9c852f Chore: Update copyright dates somewhat
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-01-01 01:31:10 -08:00
Christopher Snowhill
eb72b73e6c FFmpeg: Move some error buffers around
Since in one case, it probably wasn't combining them into one stack
allocation, it probably blew up the stack allocation quite a bit.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-12-09 18:04:56 -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
59f3f416ba Updated VGMStream to r1951-102-gf1483e22
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-12-04 23:14:53 -08:00
Christopher Snowhill
7e3112efc0 Updated libOpenMPT to version 0.7.12
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-12-04 23:14:47 -08:00
Christopher Snowhill
afe65df6c6 Minor corrections to Polish translation
mpan told me these were broken, oops. One of them
may as well not be translated until it gets a proper
translation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-11-24 21:30:28 -08:00
Christopher Snowhill
f5be598311 Add support for custom Dock icons while running
The emoji labeled buttons will convert and save their respective
state icon to the settings folder, and refresh the current icon
as necessary.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-11-24 21:30:22 -08:00
Christopher Snowhill
aa491fe0bb Updated VGMStream to r1951-100-g73ef7c6c
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-11-24 15:09:07 -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
db5b4e68c2 Updated libOpenMPT to version 0.7.11
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-10-30 23:58:46 -07:00
Christopher Snowhill
820a1dedfb Updated VGMStream to r1951-88-g02d3c3f8
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-10-30 23:58:13 -07:00
Christopher Snowhill
ef8dd958ae Reorder project file entries with a sort 2024-09-20 22:25:23 -07:00
Christopher Snowhill
eba9dc2c43 Remove unused variable 2024-09-20 22:25:17 -07: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
2e5140a321 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:25:02 -07:00
Christopher Snowhill
edbdc8d98e Update Github workflow
Update checkout and upload artifacts to latest versions
2024-09-17 02:42:04 -07:00
Christopher Snowhill
a3e6636731 VGMStream: Fix fade time configuration
Fade time was reading from some completely wrong
configuration field name, so fades weren't working.
2024-09-17 02:26:07 -07:00
Christopher Snowhill
389f56e392 VGMStream: Change render API, allocate off heap
Change to the future render api, hopefully float support
will be available eventually. Also change to allocate the
sample buffers from the heap instead of the stack.
2024-09-17 02:26:01 -07:00
Christopher Snowhill
de24bd4560 Updated VGMStream to r1951-50-g1d836a36 2024-09-17 02:25:20 -07:00
Christopher Snowhill
fcddcdce61 Updated VGMStream to r1951-0-g4b2dc01c
Updated to add one new extension, too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-23 23:07:13 -07:00
Christopher Snowhill
ba91d2e5ba Downgrade SwiftPM pins format version number
Apparently Github's old ass version of Xcode can't handle a 3 instead
of a 2 here. Whatever.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-18 04:13:10 -07:00
Christopher Snowhill
b997a6d5dc Downgrade Firebase to version 10.x
Version 11.0 requires macOS 10.15, and I haven't raised the minimum
deployment version that far yet.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 15:36:31 -07:00
Christopher Snowhill
63264de462 Update Firebase SDK to version 11.0.0 minimum
This should fix the Framework packaging issues App Store noticed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 15:31:20 -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
d3415a3a25 Updated libOpenMPT to version 0.7.9
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 03:34:02 -07:00
Christopher Snowhill
03b52685bd Update PluginController.mm
Add missing definitions to the Info.plist template generator.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 03:23:29 -07:00
Christopher Snowhill
4d11ba266e Update Info.plist.template
Clean up duplicate definitions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 03:23:22 -07:00
Christopher Snowhill
6dd01e07c1 Updated VGMStream to r1917-201-g7ab622d3
Also updated filename extensions,  and the interface plugins.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2024-08-17 03:23:08 -07:00
Christopher Snowhill
b701a4d347 Placeholder commit for Sparkle update 2024-08-07 23:17:22 -07:00
Christopher Snowhill
9f0ef52fd4 Update FFmpeg to version 7.0 and rebuilt soxr
Rebuilt libsoxr, which now removes the dependency on libavutil.
2024-08-07 23:17:04 -07:00
Christopher Snowhill
42ea824972
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:42 -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
bc330e75f6
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:33 -07:00
Christopher Snowhill
87684a7974
CI: Hopefully fix this time
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-04 02:10:34 -07:00
Christopher Snowhill
5e27f084e9
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:38 -07:00
Christopher Snowhill
8997ffa030
Update libFLAC to version 1.4.3
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 22:59:34 -07:00
Christopher Snowhill
2fc42ccb73
CI: Switch to Xcode 15
Apparently, the build images are broken or something.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 22:02:52 -07:00
Christopher Snowhill
1eee2fbf11
CI: Switch to latest macOS and latest stable Xcode
Switch the CI image to the latest stable OS version, and latest stable
Xcode version, selected by another action.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 21:29:59 -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
1f497ee8bb
Added Usage Description translations
Spanish translation provided by Kevin López Brante.
Polish, Russian, and Turkish translations of specifically these messages
provided by GPT-4, to be replaced by human translations if our
translators offer them, but it's been a while since I've gotten an update
out and I didn't really want to wait so long.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 20:35:50 -07:00
Christopher Snowhill
73252a8928
Reduce audio buffering slightly again
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 19:46:30 -07:00
Christopher Snowhill
b07a6fd098
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:35:20 -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
4ced731194
Replace hard coded Pi constant with M_PI
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:01:03 -07:00
Christopher Snowhill
8c67b6c2f7
Significantly improve memory usage of loading tags
This especially helps with bad or brutal files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:59 -07:00
Christopher Snowhill
d88a90e5b0
Fix a typo
Notifcation -> Notification

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:55 -07:00
Christopher Snowhill
122b6d6a6d
Improve audio buffering situation
Buffer up to 20 seconds per stage, and buffer only up
to 2 seconds before starting the next stage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-03 05:00:51 -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
4ddca15a8f
Simplify HRTF filter, change option to reflect it
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:57:11 -07:00
Christopher Snowhill
919661c9e8
Attempt to stabilize visualization flutter
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:57:06 -07:00
Christopher Snowhill
cfd5b1c6fb
Fix converter after output switchover
This was missing, too.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:57:01 -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
e59c7be0b8
Update BASS and friends for Xcode 15
This is needed for the Intel build target to work.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:56:44 -07:00
Christopher Snowhill
9e96bb2b75
Add missing Info.plist strings
These strings were added to the InfoPlist translations in a
previous commit, but likely need to be added to the
Info.plist file directly as well.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:56:39 -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
5e36affad8
Hopefully fix crashes from rapidly skipping files
Do this by serializing the background thread actions against
the AudioPlayer object, so we don't start playback multiple
times at once.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-10-02 10:56:28 -07:00
Christopher Snowhill
e85b5eea34
Privacy - Added Spanish translation
Translation provided by team member, Kevin López Brante.
2023-09-03 16:51:50 -07:00
Christopher Snowhill
f3d218fd3d
Privacy: Added purpose strings
The other translations currently have placeholders, awaiting translation.
I may end up using machine translation from Deepl just for Russian,
Polish, and Turkish, until I get human translations from a contributor.
Spanish will be provided by our team later tonight.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-03 16:39:04 -07:00
Christopher Snowhill
f54dd1c7b1
Playback: Start playback and seek in the background
Perform playback start and seeking operations in the background, instead
of on the main thread, which should help prevent them from stalling the
user interface.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 22:28:05 -07:00
Christopher Snowhill
d4196a5595
Updated Translations
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:42:05 -07:00
Christopher Snowhill
09c9711b50
Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:42:00 -07:00
Christopher Snowhill
40b5bf7e13
Updated VGMStream to r1866-46-g883d796d
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:56 -07:00
Christopher Snowhill
fb208b4cd5
MainMenu: Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:50 -07:00
Christopher Snowhill
57158da628
AppleScript: Implemented Composer field
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:46 -07:00
Christopher Snowhill
a01d9ee5b3
Info Inspector: Implemented Composer field
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:42 -07:00
Christopher Snowhill
9593902aff
Playlist: Implemented Composer column
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:37 -07:00
Christopher Snowhill
a3c8149612
Tags: Expose Composer tag through interfaces
Implement the composer field interface to playlist item tag
reading and writing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:33 -07:00
Christopher Snowhill
1bffcaa429
TagLib: Remove stray whitespace
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:29 -07:00
Christopher Snowhill
d62d5f1279
TagLib: Implement Composer tag support
Most of the reading was already there, it just didn't expose
it to the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:24 -07:00
Christopher Snowhill
11dcac6b04
ASF/WMA: Implement Album Artist tags (oops)
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-09-02 21:41:20 -07:00
Christopher Snowhill
5b9e5be295
Add a bitrate column to the playlist
Adds a bitrate column to the playlist view, which is fully sortable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:48:22 -07:00
Christopher Snowhill
0f6b403b43
Fix rating sorting
This apparently fixes sorting by rating.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:48:17 -07:00
Christopher Snowhill
03e510fa92
Add missing column header translations
These column header names were missing from the strings
tables. Add them based on existing translations of the same
field names by our translators.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:48:12 -07:00
Christopher Snowhill
1dbaa61313
Touched by Xcode
Miscellaneous XIB changes automatically applied by Xcode
when editing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:48:07 -07:00
Christopher Snowhill
bfe2f03fbb
Fix sorting for missing columns
This should fix the sorting for rating, sample rate and bits per sample

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:48:02 -07:00
Christopher Snowhill
702a52a93e
Attempt to make project build with Xcode 15
This is supposed to fix running on macOS 10.13, but it doesn't.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-08-20 23:47:58 -07:00
Christopher Snowhill
eae6c96b5e
Reduce inter-thread buffering a bit
This isn't needed so much now that the output buffers more.

Should reduce the problems of #370

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37:37 -07:00
Christopher Snowhill
fc2d96831d
Don't pause streams, stop instead
Do not bother to pause streamed files, instead stop playback when pause
is requested.

Fixes #372

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37:33 -07:00
Christopher Snowhill
587ccd6a0d
Fix Repeat menu being disabled, change default
Default repeat mode should now be Repeat All, and the menu items should
now all function, fixed by removing a bunch of pointless attributes from
each affected menu item.

Fixes #371

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37:29 -07:00
Christopher Snowhill
a4ff143600
Touched by Xcode
Resource scripts touched by Xcode again

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-29 01:37:24 -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
f642a066f8
MIDI: Properly bundle the BASS Musepack plugin
This is imported by the player, though it doesn't fail when it's
missing, so that would explain why I didn't spot this error sooner.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 02:41:26 -07:00
Christopher Snowhill
fa1b632a59
MIDI: Stop linking BASS plugins directly
They'll be imported by the plugin on startup anyway, and they don't
really have any exported functions we can use.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 02:41:21 -07:00
Christopher Snowhill
d3ca6c390c
Disable dead code stripping
No idea why this was enabled, no idea if I should disable it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 02:41:14 -07:00
Christopher Snowhill
99578a333e
APL+CUE: Revert pointless change
This change served no purpose, other than to confuse me. I must need
some sleep already.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:25:11 -07:00
Christopher Snowhill
c3070e5f39
APL: Stop on the correct sample
This should stop before the specified end point, not one sample later.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:20:04 -07:00
Christopher Snowhill
dd7340d6d5
APL: Fix position handling for DSD
Correctly scale the AudioChunk frame counts. This more and more makes me
think I should be scaling this in the AudioChunk code instead, but then
code may not know about the special case of every 8 frames only being
one byte per channel.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:53 -07:00
Christopher Snowhill
e7d6ab88ce
APL: Round bits per sample to an even byte
Round this variable up.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:49 -07:00
Christopher Snowhill
16072b3af3
CUE: Fix playback position tracking for DSD
DSD wasn't tracking the correct sample count, because DSD
Audio Chunks store the byte count, rather than the bit count.
This may be changed in the future, so I'll have to remember.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:44 -07:00
Christopher Snowhill
440ba24c57
CUE: Stop on the correct sample
Stop before the end, rather than on it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:40 -07:00
Christopher Snowhill
37fc054739
CUE: Round up bits per sample
Round bits per sample to an even byte.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:36 -07:00
Christopher Snowhill
8ad84c3aed
Add status messages to updater script
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-21 00:18:31 -07:00
Christopher Snowhill
2d7a7480d9
Add an option to control halving DSD volume level
And default it to disabled. As was pointed out to me by a user, DSD is
apparently mastered to a level of -6 dB, so double its level on output
by default.

Also reorder all preferences dialog controls so they are instantiated in
display order, which should help screen readers, maybe.

Fixes #368

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-15 16:46:39 -07:00
Christopher Snowhill
09aa0d96e1
Work around rounding error with resampler flush
Resampler flush may indefinitely produce 1 sample if there is a rounding
error with the buffering calculations. Work around this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 05:16:34 -07:00
Christopher Snowhill
3d24168ba7
Fix clipped sample rate changing between files
When the clipped sample rate changes, the resampler needs to be
restarted. This was previously failing because the target sample rate
wasn't changing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 05:16:30 -07:00
Christopher Snowhill
323a554832
Fix lossless capability reporting for partial read
When reading partial chunks, and when returning partial data, it is
essential to maintain this lossless chunk status across either whole or
partial chunk reads. Otherwise, the converter chain sees the lossless
flag constantly changing on lossless files, such as PCM or DSD, and
causes the DSD decimator and/or resampler to be torn down and reset
repeatedly, causing glitches in the audio.

The glitch was not, in fact, with the decimator itself, and was
occurring to a degree without it, as it would be restarting the
resampler repeatedly as well.

Fixes #367

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:14:14 -07:00
Christopher Snowhill
ffbc571660
Correct the decimator sample latency
The latency is half of the FIFO, or half the filter size, and each byte
is 8 samples, so return the value accordingly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:11:04 -07:00
Christopher Snowhill
efd1349a59
Add an explanatory comment that got lost
This comment was in the original sample decimator code, I neglected to
include it in my port over to Cog. Doesn't really serve any functional
change, though. It would have clarified that I needed to reduce the gain
level much sooner, though.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-07-14 04:10:10 -07:00
Christopher Snowhill
728ae813c5
Updated libOpenMPT to version 0.7.2
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:32:01 -07:00
Christopher Snowhill
0be8dbe7c5
Updated VGMStream to r1843-92-g740a4048
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:31:49 -07:00
Christopher Snowhill
270cf79bb7
Change default open to enqueue and play
Instead of clear playlist and play. This was confusing people,
apparently. I should have changed it sooner, since this is what
I use normally anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:31:34 -07:00
Christopher Snowhill
0efc3d4ad7
Add fade global shortcut
Defaulting to ctrl-cmd-O, though I may change this if
someone has any better ideas for a default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:31:10 -07:00
Christopher Snowhill
0fb28001f9
Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:30:48 -07:00
Christopher Snowhill
207fee1a50
Change "Spam" to "Copy now playing"
Change the not-obviously-named shortcut to something more
obviously named after its purpose.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-30 23:30:03 -07:00
Christopher Snowhill
a366cbadee
Remove a saucy option
Nobody was likely to be using it, much less even know what it was.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-13 22:42:13 -07:00
Christopher Snowhill
3c91aab9d8
Updated BASS and company
Also included missing BASS_MPC, which was still being imported
even though it wasn't actually included.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-12 17:29:01 -07:00
Christopher Snowhill
3689fb51f8 Update MASShortcut for Xcode 15
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:40:44 -07:00
Christopher Snowhill
e1e5c22b8a Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:40:32 -07:00
Christopher Snowhill
cb0ae6db6c
Organya: Fix deployment target for 10.13
Oops, it was somehow still set to 13.0, from when I created it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:15:41 -07:00
Christopher Snowhill
39459b89cb
Update projects and source in prep for Xcode 15
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:14:45 -07:00
Christopher Snowhill
5aaea62b54
About Dialog: Move logo to asset catalog
Also convert it to a supported HEIF format, making it much smaller.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-08 04:14:38 -07:00
Shoh Sewell
baf9797907 Volume slider changes
Makes volume slider logarithmic when limited to 100% to allow easier changing of volume towards the bottom of the slider.
The tooltip remains as the slider location instead of the logarithmic value of the actual volume.
2023-06-08 02:10:15 -07:00
Christopher Snowhill
dd630ba394
File Tree: Reduce monitoring to limited changes
Only track new, removed, or renamed files. Tracking Xattr changes was
apparently causing the tracker dialog to crash on things like the user
changing file type associations, which either added or removed a per-
file association xattr, or when clicking Change All, removed this xattr
from all associated files tracked by Spotlight.

Fixes #361

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-04 01:37:46 -07:00
Christopher Snowhill
a640627fe1
Playlist: Add a workaround for AppleStript URLs
AppleScript is apparently such a legacy system, that when it sends URLs
to your app to open, they're in the old Carbon format. So we need to
translate these to proper URL strings for the rest of the app to deal
with them at all.

The format of these URLs is as follows:

/method/::

Followed optionally by:

username/password@

Where the slash and password are optional.

Followed by:

hostname

Followed optionally by:

/portnumber

And finally, followed by:

:path:on:server:filename.ext

So, in hostname field, we must swap slashes to colons. And in the path
field, swap colons to slashes. What a bizarre world.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 21:34:34 -07:00
Christopher Snowhill
5550af7e64
HTTP Input: Do not hang if transfer completes
If transfer completes quickly, do not hang waiting for it to achieve
reading state. Also add some comments indicating what we're doing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 21:34:29 -07:00
Christopher Snowhill
e0a1cf49e7
Metadata: Fixes metadata reading
metadataBlob may be null, so create dictionary in that case.

Fixes #360

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 15:15:36 -07:00
Christopher Snowhill
391b9cf6dc
Update feed updater script for R2
Update to use rclone with out of tree config to upload

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-06-01 00:15:03 -07:00
Christopher Snowhill
689010b714
Playlist: Fix merging dynamic metadata dictionary
Merge the existing metadata entry dictionary with new values, because
sometimes, the caller may pass us a dictionary with some fields missing.

Fixes stream metadata for many HTTP streams.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:36:04 -07:00
Christopher Snowhill
c88c9e9aa0
HTTP: Support a stream title hack
Support a stream title hack employed by some iHeartRadio streams

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:36:00 -07:00
Christopher Snowhill
90eb2ded1d
HTTP: Support much larger metadata blocks
Support icy metaint data blocks up to 4KiB in size

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:35:45 -07:00
Christopher Snowhill
7640c869de
Updated VGMStream to r1843-0-gb158e812
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:35:40 -07:00
Christopher Snowhill
1ef7853488
FFmpeg: Fix AAC streaming
Fix AAC streaming by adding the correct audio/aac MIME type.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-31 22:35:36 -07:00
Christopher Snowhill
e7692dc40b
Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:23:06 -07:00
Christopher Snowhill
b9768e8100
Updated Turkish translation to near completion
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:22:53 -07:00
Christopher Snowhill
d2adf39e04
Updated VGMStream to r1831-27-ge6883cbd
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:22:08 -07:00
Christopher Snowhill
dfa5f41984
Updated libOpenMPT to version 0.7
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-05-04 18:20:54 -07:00
C.W. Betts
49bfd5053f Move most image assets to Xcode assets.
AboutCog.jp2 isn't moved because Xcode/Xcode assets doesn't recognize jp2 files as images.
2023-05-03 17:59:50 -07:00
Shoh Sewell
9c5a7d0e3e
Adds decimal digits to volume slider tooltip (#356)
* Adds decimal digits to volume slider tooltip

Modifies the volume slider tooltip so that:
-If the volume slider falls below 10%, the volume tooltip will display one decimal digit of precision (e.g. 3.4%).
-Else if the volume slider falls below 1%, display one decimal digit of precision (e.g. 0.34%).
-Otherwise display the volume slider tooltip as normal.

This helps show changes in volume between 0% and 10% where a change in volume isn't shown in the UI but is heard (especially when the "Limit volume control to 100%" option is unchecked in the "Output" Preferences submenu.

* Update VolumeSlider.m

Fix variable declaration

---------

Co-authored-by: Christopher Snowhill <chris@kode54.net>
2023-05-03 17:59:24 -07:00
Christopher Snowhill
07680673f8
Translation: Added Turkish language support
This translation is mostly complete.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 22:44:43 -08:00
Christopher Snowhill
37de4dc447
Translation: Updated Spanish translation
Added the new Lyrics window strings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 22:44:38 -08:00
Christopher Snowhill
55e28973d1
Main Menu: Add new Lyrics item to strings tables
Add item to strings tables for translations of the menu item. English is
already done as the base language, awaiting Spanish at least, will await
Polish and Russian when the respective translators get to it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:25:46 -08:00
Christopher Snowhill
e7b0b8bbb1
Lyrics Window: Added localization templates
Awaiting localizations of the window name in currently supported
languages.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:18:50 -08:00
Christopher Snowhill
3347cbf1da
Lyrics Window: Touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 18:18:03 -08:00
Christopher Snowhill
48f339f25b
Info Window: Reorder header imports
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:32 -08:00
Christopher Snowhill
420d706979
Lyrics: Implement Lyrics window display and hotkey
Implement Lyrics window display into main app as a popup window panel,
with a main menu hotkey.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:27 -08:00
Christopher Snowhill
8eaafe8f9b
Tags: Implement unsynced lyrics in Vorbis plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:23 -08:00
Christopher Snowhill
7b98a64035
Tags: Implement unsynced lyrics in Opus plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:19 -08:00
Christopher Snowhill
403f02f961
Tags: Implement unsynced lyrics in Flac plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:15 -08:00
Christopher Snowhill
abbb2fece7
Tags: Implement unsynced lyrics in FFmpeg plugin
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:11 -08:00
Christopher Snowhill
e66b01b6db
Tags: Implement unsynced lyrics into TagLib plugin
Implement unsynced lyrics reading into TagLib frontend plugin.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:08 -08:00
Christopher Snowhill
a21242db55
TagLib: Implement unsynced lyrics tag support
Implement unsynced lyrics tag reading and writing into TagLib.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:47:04 -08:00
Christopher Snowhill
7e2a286b83
Tags: Added unsynced lyrics tag interface
Added an unsynced lyrics tag interface to the PlaylistEntry class

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-23 17:46:59 -08:00
Christopher Snowhill
ed281eb743
Update copyright year in various places
Update these things a bit for the next release.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-05 16:46:31 -08:00
Christopher Snowhill
d5720e3944
Updated VGMStream to r1810-97-g408cada5
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 23:52:34 -08:00
Christopher Snowhill
66338e2c83
Updated libOpenMPT to version 0.6.8
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 23:51:44 -08:00
Christopher Snowhill
4617654b57
Repair SceneKit project definition
Repair the SceneKit container definition in the Xcode project file, so
that the Visualization scene gets copied properly on project build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 23:48:04 -08:00
Christopher Snowhill
d4785e0c74
Replaced r8brain with libsoxr
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2023-02-04 23:47:54 -08:00
Christopher Snowhill
e1fb7b9bd7
Playback Controller: Fixed title bar updating
This change had several components. For one, the delay of the dispatch
was increased from 5 milliseconds to 50 milliseconds. Two, the post to
the notification center was included in the delayed dispatch, so that
retains the PlaylistEntry object. Finally, the playlistController's
currentEntry object is reassigned from the input PlaylistEntry object,
which facilitates all watchers which are observing that variable for
updates. This final step also retains self for the callback, which
should be fine, since it's a quick dispatch with a short delay.

Fixes #335

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 22:34:47 -08:00
Christopher Snowhill
9822dcc4c0
Audio Player: Only wait for unstopped input
Input thread now signals when it has stopped and is about to return, in
case the input thread returns before the BufferChain dealloc function
would be waiting for it to terminate. Somehow, even though the Semaphore
is being signaled at this point, the BufferChain still ends up waiting
the default of 2.5 seconds for the signal that apparently never comes,
delaying file stoppage. This prevents the wait action entirely. Must
have been some sort of race condition.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:17:45 -08:00
Christopher Snowhill
447a60afd9
Audio Player: Add new method of signaling stop
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>
2022-12-09 21:14:45 -08:00
Christopher Snowhill
4f942ac890
Playback Controller: Remove "stopping" status use
This should not really be necessary for proper player operation any
longer, and can safely be removed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:13:12 -08:00
Christopher Snowhill
02c5ccaae1
Sandbox: Rework several blocking actions
Several actions have been reworked to be non-blocking, as their
operation should still occur in the main thread, but should not block
the thread they are called from, as they are not required to continue
processing there.

End of secure access has also been made non-blocking, as it is usually
only called when an input is done accessing a given file or folder, so
it should be important to return quickly, as the input is likely about
to terminate, and other things are waiting for it to return.

Also remove a nested block call for the storage access, as it is within
an existing serializing block, so it shouldn't need to be nested.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-09 21:12:33 -08:00
Christopher Snowhill
e8caede273
Update script: Purge cache of manifest files
Purge the manifest files from the Bunny CDN cache before starting
the update of the site.
2022-12-05 23:18:29 -08:00
Christopher Snowhill
1c09694f1b
Decoders: Implemented Organya decoder
Based on the C++11 code by Joel Yliluoma / bisqwit, which in turn is
based on information from NX-Engine. I have also taken the liberty of
bundling the required wavetable bank and PixTone drums. Contrary to the
documentation provided with the code, my version of dou_1006.zip, as
downloaded over a decade ago, had the wavetable bank at offset 635,816
bytes into the file, not 1,115,748 bytes. Possibly a difference of
having applied the translation patch? My copy is the original version,
so I had to use a real resource parser to locate the waveforms.

The player will obey the configured sample rate, loop count, and fade
time for synthesizers, and also obey Repeat One to play indefinitely.
The code should be quite robust to minor abuses, though I can't imagine
how well it would hold up to random bad files, other than playing
outright garbage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-04 03:03:45 -08:00
Christopher Snowhill
6023acc10e
Sandbox: Fixed another outstanding sync bug
Releasing sandbox access was incorrectly synchronizing on the object,
but still running code in the calling thread. It has been updated to
match the rest of the interface, which serializes all access through the
main thread only. This should prevent the sandbox from carrying stale
handles to already-released objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-03 22:13:14 -08:00
Christopher Snowhill
466d07dccb
Resampler: Update r8brain-free-src to v6.2
This should improve performance significantly for downsampling.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-12-03 22:10:50 -08:00
Christopher Snowhill
547f4ea012
Fix SceneKit visualization
Must always remember to have xcode-select set to Xcode.app and not
the Command Line Tools when archiving the app myself, as otherwise
Xcode will fail to package the SceneKit objects into the resulting
bundle.
2022-11-30 01:12:15 -08:00
Christopher Snowhill
d7d6014789
Sandbox Broker: Fixed a potential reference crash
The code which looked up Sandbox handles for a given path had a bug
where it would re-add the handle to the in-memory cache storage even if
it already had just retrieved the current handle from the cache. I hope
this will fix the crashes which have been plaguing people adding a lot
of files to the playlist all at once from a single folder.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:54:16 -08:00
Christopher Snowhill
ecd46cfa3c
Updated VGMStream to r1800-25-g599326a3
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:54:05 -08:00
Christopher Snowhill
cd55a0b08c
Dependencies: Update libVGM release and debug
Update from 0e34925..fd7da37, with the following changes:

- C140: simplify update loop, add unbanked mode
  - It resembles MAME's code more closely now.

- OKIM6258: make more tolerant against late writes

- enforce "discrete YM3438" mode for YM3438 VGMs

- Update emu2413 to v1.5.9

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-29 00:49:43 -08:00
Christopher Snowhill
56ea4a5428
Update Script: Change feed upload to Bunny CDN
Change upload script to use curl to upload to Bunny. The access
key is stored in the system keychain, with confirmation on access.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-07 00:00:19 -08:00
Christopher Snowhill
c850d7752f
Vorbis Plugin: Remove unnecessary shell script
Remove shell script that was modifying the import path of a framework,
as we are no longer using libvorbis like that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-06 00:50:01 -07:00
Christopher Snowhill
1d1babd2bb
Add display name and category to project
Add display name and category fields to project. Thanks, Apple, for
adding those to Xcode all of a sudden.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-05 00:48:57 -07:00
Christopher Snowhill
08f2dabc81
Info plist: Add newly required keys
For some reason, Xcode isn't adding these now. No idea what Apple
has done to cause this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-05 00:43:43 -07:00
Christopher Snowhill
445b1bb295
Sandbox Broker: Fix hang with synchronization
Synchronize with dispatches to the main thread instead of using
synchronization primitives. This prevents the main thread from
hanging another thread as a result of other threads entering the
sync block, then dispatching a callback to the main thread, which
also tries to lock on the sync block.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-11-04 21:14:19 -07:00
Christopher Snowhill
4bed0af868 Core Data Store: Handle concurrency properly
All concurrency from other threads should pass through the viewContext's
performBlock or performBlockAndWait functions, and no other way. So now,
all access to Core Data is either happening on the main thread, or by
using these code blocks, all of which will wait for their access to
proceed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-30 16:54:52 -07:00
Christopher Snowhill
e3ae28369f MIDI Plugin: Fix Secret Sauce memory leaks
Needed some autoreleasepools in there.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-28 00:17:08 -07:00
Christopher Snowhill
48056a9a2e Touched by Xcode
Xcode updated the Preferences xib.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-28 00:17:03 -07:00
Christopher Snowhill
5011f59b34 Sync commits 2022-10-28 00:02:46 -07:00
Christopher Snowhill
052a77d2cc MIDI Plugin: Add a little Secret Sauce
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-27 23:06:14 -07:00
Christopher Snowhill
bcd5ab0dd2 Amend MIDI Audio Unit player a bit
This should fix some potential initialization errors it may have had
before, but this doesn't fix the broken Sound Canvas VA plugin. Roland
says it's supposed to be broken on macOS 12+ and/or Apple silicon
anyway, so I guess there's no dodging that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-21 16:37:14 -07:00
Christopher Snowhill
5882affd3f Always create new ContentViewController for volume
This is needed to re-parent the VolumeSlider window, as there is only a
single VolumeSlider, but two different VolumeButtons and their
respective NSPopover windows. So, always recreate the view on open,
which doesn't appear to have a noticeable impact on performance.

Fixes #331

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-20 21:28:20 -07:00
Christopher Snowhill
034863ee38 Fix Spectrum View in toolbar customizer
It was referencing the old SpectrumView class, when it should have been
referencing the safe SpectrumViewCG class, which will software render a
single frame of spectrum data when the customizing dialog is opened.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-20 21:28:15 -07:00
Christopher Snowhill
b5e096180a Updated FFmpeg to n5.2-dev-1305-g3bd0bf76fb
Among other things, fixes CVE-2022-2566.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-17 03:55:49 -07:00
Christopher Snowhill
54f46d6380 Ignore unnamed audio devices on enumeration
This was crashing trying to assign a nil CFStringRef from mystery audio
devices to the NSString passed to the enumerate block function, which
was predictably crashing. Ignore such devices instead.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 15:23:14 -07:00
Christopher Snowhill
ab512e5086 Handle external artwork with .heic extension
External artwork already supported the HEIC format, just not the correct
filename extension for the format.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 15:00:06 -07:00
Christopher Snowhill
e4bc5853ad Fix a crash with embedded cue sheet handling
Tag reading can read cue sheets as either a single NSString, or an
NSArray of NSStrings, so handle either case.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-16 14:59:19 -07:00
Christopher Snowhill
cddf9fb9ba Sync commit count 2022-10-16 00:19:32 -07:00
Christopher Snowhill
ee5231f567 Only process visualizations when visible
Stop visualization processing when the host window is completely
occluded, thus reducing background CPU usage levels significantly

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-15 23:19:36 -07:00
58a3c3aeeb
Merge pull request #329 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2022-10-13 21:13:37 -03:00
The Gitter Badger
29f20c60c1 Add Gitter badge 2022-10-14 00:07:50 +00:00
Christopher Snowhill
fba0775ebd Update associated file type extensions
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:17:54 -07:00
Christopher Snowhill
3a98f3f5a1 Formatting fixes
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:09:09 -07:00
Christopher Snowhill
c9181f571f Better locking behavior for playlist storage
This should fix up potential locking issues with maintaining a copy of
the results set while certain other background actions may happen, such
as the player updating play counts while playing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:09:05 -07:00
Christopher Snowhill
e54d05a907 Updated libraries and libraries debug set
Updated:
- libFLAC from 1.3.3-235-g772efde6 to 1.4.1
- libvgm from 001ca75 to 0e34925
- libid3tag from 0.16.1 with patch to 0.16.2

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:09:01 -07:00
Christopher Snowhill
894aada3d2 Updated libOpenMPT to version 0.6.6
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:08:56 -07:00
Christopher Snowhill
929ab11738 Updated VGMStream to r1776-97-g845961bb
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-10-11 23:08:51 -07:00
Christopher Snowhill
7ad895b95c Updated VGMStream to r1776-46-gc0c2c3c7
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-09-06 21:57:24 -07:00
Christopher Snowhill
9a7ecd98ea Update translations
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 16:50:34 -07:00
Christopher Snowhill
dffd09e6f7 Updated VGMStream to r1776-16-g7e4f5dc6
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 16:31:05 -07:00
Christopher Snowhill
d03afd6bf8 Updated libOpenMPT to version 0.6.5 final
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-21 16:31:01 -07:00
Christopher Snowhill
58453a6b7d [Cog Audio] Rename Semaphore.h to CogSemaphore.h
This magically fixes the stupid header maps that were pulling the system
semaphore.h into Swift projects, when they shouldn't have been doing
that in the first place. This is the same reason that the FLAC library
has its assert.h renamed to FLAC_assert.h.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 22:18:40 -07:00
Christopher Snowhill
be87e5433c [Cog Audio] Make the Swift Vis Controller work
And this is the actual meat of getting it to work properly, the changes
the Swift code needed to actually be fully functional.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:38:58 -07:00
Christopher Snowhill
e630b34981 [Cog Audio] Add a Swift bridging header
This makes the Swift version of the Visualization Controller usable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:38:54 -07:00
Christopher Snowhill
8db5386053 [Cog Audio] Change a couple of imports
These imports needed to be changed so that Swift bridging didn't import
the system's semaphore.h instead of CogAudio's Semaphore.h, which is a
completely different thing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-05 21:38:50 -07:00
Christopher Snowhill
cbeba3fa0e First module converted to swift, but broken 2022-08-05 21:38:44 -07:00
Christopher Snowhill
a8fea3f657 [GME Input] Correct old comment in the code
There has been an API in GME to detect tracks ending for quite some time
now, and this just adds a little bit to the existing comment, which
previously noted that there was no way to detect if a track had ended,
which may have been true several major versions of GME long past.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-04 18:03:04 -07:00
Christopher Snowhill
5ac279e289 [GME Input] Fix decoder output sample count
The output has been assigning twice as many samples as it was supposed
to ever since commit 8d851e5bda, which
ended up generating the correct 1024 samples (2048 per GME parameter),
but assigned 2048 to the AudioChunk, which resulted in over-reading the
audio buffer, and thankfully not crashing, but instead causing an awful
sound distortion effect as random memory contents were played as PCM
audio.

Fixes #320

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-04 18:03:00 -07:00
Christopher Snowhill
4480eeefbe [CUE Sheet Container] Allow other containers
Allow .mp3 and such to fall back to the FFmpeg container handler, in
case there are chapters in a renamed file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:21:22 -07:00
Christopher Snowhill
4d1d799f98 [MAD Decoder] Do not close source ourselves
The input isn't supposed to close its own sources, as it did not open
them itself, and they should be cleaned up automatically when they are
released to zero reference count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:21:18 -07:00
Christopher Snowhill
ad8c59be2a [MAD Decoder] Drop RIFF files to the next input
Let the FFmpeg decoder handle RIFF files, if they happen to be named
.mp3 and not something like .wav.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:21:14 -07:00
Christopher Snowhill
545385da59 [Update Script] Add new JSON generator
Source is included here:

https://github.com/losnoco/sparkle-to-JSON
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-08-03 21:21:11 -07:00
Christopher Snowhill
59ab4ccdb5 Fix update script
This fixes the update URL and parameter handling. Seems there
was an extraneous newline returned by the security command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 23:44:12 -07:00
Christopher Snowhill
4d3274362c [AdPlug Input] Fixed seeking
Looks like I never tested this, meh.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 22:52:13 -07:00
Christopher Snowhill
233dc424cb Update update_feed.rb with new parameter
New parameter for update title for the site generator.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:51:25 -07:00
Christopher Snowhill
3a64cdd5cc Updated AdPlug with a crash fix for RAD2
Fixed RAD2 files referencing instruments not present in the
file, which caused the player to reference uninitialized memory
and usually crash.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:51:21 -07:00
Christopher Snowhill
0bae420e6b Updated libbinio
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-31 21:51:16 -07:00
Christopher Snowhill
a4327579fa [Playlist Menu] Disable actions on empty selection
These actions should not be invoked when there is no selection.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:43:04 -07:00
Christopher Snowhill
ff1afdb63c [Playlist Queue] Save queue state change to disk
Save queue state changes to disk, rather than leaving it for later.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:43:00 -07:00
Christopher Snowhill
e0c1e338e4 [Playlist Queue] Hopefully prevent a crash state
This removal was causing crashes for some people. It should not get this
way, however.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-29 01:42:56 -07:00
Christopher Snowhill
b60a5462b7 [SID Input] Add static initializer for residfp
The SID builder needs a static initializer, otherwise multiple instances
created simultaneously, such as during populating info on adding a lot
of tracks, will race and crash the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 21:38:33 -07:00
Christopher Snowhill
3ff9d079d7 [File Tree] Only free Smart Folder query if used
Only free the query if it was successfully allocated.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 06:35:45 -07:00
Christopher Snowhill
9113051840 [File Tree] Ask Sandbox for access to Smart Folder
Ask for access to Smart Folder dictionary file, to read its query.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-27 06:35:04 -07:00
Christopher Snowhill
a2dacc067b [Playlist View] Prevent assigning nil textField
Prevent somehow assigning nil textField contents, as well as the
tooltip text.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:55:54 -07:00
Christopher Snowhill
03c498c0fc [Playlist Loader] Extend deduplication to CUEs
CUEs will now deduplicate playlist entries based on their dependencies,
and prevent loading redundant tracks if you add an entire directory, or
use the option to add a directory when adding single files from it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:35:11 -07:00
Christopher Snowhill
59ac5769ad [Sandbox] Add Sandbox grants to places missing it
The subdirectory parser, the CUEsheet reader, and the legacy XML
playlist reader were missing grants for Sandbox access.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-25 19:33:51 -07:00
Christopher Snowhill
9752cb725e Spanish translation of new option.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:23:28 -07:00
Christopher Snowhill
f36ec30cb3 Clarified folder add message to correct button
Clarified the button name to "Open", which is what the button actually
says, not "OK". Also used double quotes around the other button name.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:23:24 -07:00
Christopher Snowhill
77b3d74948 [Sandbox Paths] Automatically clean up old paths
Clean up redundant paths automatically, and on startup. Also refresh the
preferences dialog path list every time it is opened.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:14:52 -07:00
Christopher Snowhill
7e06aef932 [Playlist Loader] Deduplicate loaded items
Deduplicate loaded tracks, to prevent duplicate items when adding a
folder that happens to contain playlists or CUE sheets referencing the
very same files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:13:03 -07:00
Christopher Snowhill
e6bafa0b38 [Playlist Loader] Add option to load more files
Add option to load every file in a folder when opening just one or more
files in that folder.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 23:12:11 -07:00
Christopher Snowhill
72350a8b4c [Playlist View] Change truncation behavior a bit
Change the truncation behavior to only truncate if the length exceeds
1024 code points.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:35:57 -07:00
Christopher Snowhill
5f87475f2d [Playlist View] Add Sample Rate and BPS fields
Add Sample Rate and Bits Per Sample columns, hidden by default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:35:10 -07:00
Christopher Snowhill
92b02c20db [Sandbox Dialog] Fix removing newly added paths
Newly added paths weren't adding all of the necessary data to the list
storage to make it possible to remove them without restarting the
player. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 19:17:04 -07:00
Christopher Snowhill
ddbc38c7fe Move most large stack using buffers to the heap
This should solve most potential future stack overflows.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 18:32:47 -07:00
Christopher Snowhill
eec8bf9f1c Enable warnings to track stack overuse
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-24 17:50:28 -07:00
Christopher Snowhill
699bdbada3 [Sandbox Notification] Add Spanish translation
Add the Spanish translation of the new dialog.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:39:26 -07:00
Christopher Snowhill
d4ce000dc3 [Sandbox Notice] Change single to double quotes
Change the quotes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:39:22 -07:00
Christopher Snowhill
de710ef402 [Libraries] Fixed OpusFile debug library
It was linking to the wrong filename for libogg.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:39:17 -07:00
Christopher Snowhill
df17e1c788 Updated VGMStream to r1745-79-g449bb5e0
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:39:13 -07:00
Christopher Snowhill
5c3b876c04 [File Permissions] Add warning dialog
Added a warning dialog to notify the user of the purpose of the add
folder dialog that will pop up after it. Otherwise, they may get the
idea that the dialog is a glitch and should be cancelled.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:04:13 -07:00
Christopher Snowhill
f9aa56b18a [Playlist Loader] Only ask permission for local
Only ask permission for container folders if the container has local
files, and not for purely remote files, such as stream playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-23 18:00:18 -07:00
Christopher Snowhill
9ced34a87c [Playlist Insert] Add a further bodge fix
I wish people would stop adding files to the playlist while there's a
search filter in place.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:16:36 -07:00
Christopher Snowhill
8f7b26cb5d [FFmpeg Input] Buffer up to 5ms each read call
Buffer up to 5 milliseconds of audio, or at minimum 1024 samples, each
call. Also pre-allocate the buffer, rather than using a stack buffer.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 04:03:21 -07:00
Christopher Snowhill
bb307a64b6 [FFmpeg Input] Do not subtract first block length
This is an unnecessary step, and results in the offset being off by the
duration of the first pre-read block. This is incorrect.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 03:54:08 -07:00
Christopher Snowhill
59d54f3190 [Inputs] Severely reduce metadata update intervals
The Vorbis, Opus, MAD MPEG, and especially the FFmpeg inputs needed to
have their metadata update intervals severely reduced, to reduce CPU
usage, especially on files with lots of tags. Interval reduced to only
once per second.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-21 03:53:14 -07:00
Christopher Snowhill
0b8a850086 [Chunk List Converter] Fix repeated initialization
Oops, this compare blunder resulted in DSD decimation breaking every
1024 samples or so, owing to block sizes, and caused ticking sounds as a
result. It would also cause HDCD decoding to break completely.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:05:40 -07:00
Christopher Snowhill
7e03f423c3 [Chunk List Converter] Minor changes
Neither of these two changes is really important, but they do simplify
things, and the division on that one function makes the non-decimating
DSD support actually functional, as the caller expects a specific number
of samples, and that was otherwise octupling the input sample count.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 23:04:25 -07:00
Christopher Snowhill
d9a09bff40 [Audio Output] Eliminated another stack buffer
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>
2022-07-19 23:03:00 -07:00
Christopher Snowhill
afa992189d Add a lock around access to output PTS variable
This locking should help, but I don't know why visualization jumps
around now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 07:31:04 -07:00
Christopher Snowhill
5314eda5ab Reconfigure default toolbar layout
Now things are a little more understandable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 07:29:38 -07:00
Christopher Snowhill
8ae271c511 [FLAC Decoder] Fix reading CUESHEET tags
It already supported reading the CUESHEET metadata block, but I managed
to break reading and processing CUESHEET Vorbis comments, which broke
CUE tagging, as well as files that didn't have both tags.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-19 04:53:46 -07:00
Christopher Snowhill
5280cd3aa3 [Playlist Pasteboard] Rewrite row pasteboard
Playlist View pasteboard copier function should only be generating URLs,
and it should verify that the entry has a valid URL to begin with.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 06:10:16 -07:00
Christopher Snowhill
7f4459c41c [Repeat Album] Add a safety test to repeat list
In case the current track isn't part of an album, or is otherwise not
matching any albums in the playlist. Though the Album filter predicate
wasn't working for a while due to changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 05:59:27 -07:00
Christopher Snowhill
0f003fcefd Update all localizations
This includes the base English strings, Spanish, Polish, and Russian.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-16 05:46:34 -07:00
Christopher Snowhill
72ed975d56 [Audio Output] Remove renderer from synchronizer
Remove the renderer from the synchronizer on stop, before releasing the
objects, if possible.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 22:52:46 -07:00
Christopher Snowhill
76d612faf4 [Audio Output] Only unregister listener if used
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>
2022-07-15 22:51:59 -07:00
Christopher Snowhill
dc536eef3d [MAD Decoder] Don't crash on bad files
The local and seekable file scanner could crash on bad MPEG files if
they failed to decode any frames and broke due to either end of file or
other unrecoverable errors, due to a division by zero error attempting
to calculate the file bitrate. Now correctly return error state if this
occurs, bailing early.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 22:51:04 -07:00
Christopher Snowhill
47258b02b1 [Core Data] Add access locking
Apparently we need this to prevent Core Data from stomping on itself
when another thread accesses it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 07:00:11 -07:00
Christopher Snowhill
7d46ac42b6 [Playlist Storage] Properly force migration
Old version users needed this, but it wasn't performed correctly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:18:39 -07:00
Christopher Snowhill
498d85a0f4 [Dependencies] Fix libogg version number
Apparently, the autotools package uses a different versioning scheme
than the CMake build. Also rebuilt and re-versioned libvorbis and
libvorbisfile.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:18:28 -07:00
Christopher Snowhill
187ee602d6 [libid3tag] Updated to avoid crash bug
Already updated to 0.16.1, but this fixes a crash bug in 0.16.1.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:18:18 -07:00
Christopher Snowhill
de9b09251d [Audio Output] Greatly improve sample rate changes
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>
2022-07-15 06:18:08 -07:00
Christopher Snowhill
4df50c7fc3 Fix the Spotlight search panel
It was previously crashing horribly on adding search results. This makes
it actually functional, and renders it using a view-based table instead.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-15 06:18:01 -07:00
Christopher Snowhill
96304dbb17 Significantly reduce stack memory usage
Oops, there were a lot of large local buffers in use here.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 17:28:24 -07:00
Christopher Snowhill
b60646a1fc Remove obsolete helpbook document
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 16:12:04 -07:00
LennyLip
ed6f0d8f52 ru FreeSurround pref string 2022-07-14 16:11:58 -07:00
Christopher Snowhill
b742fb6659 Sync with sparkle branch 2022-07-14 16:06:20 -07:00
Christopher Snowhill
d417d245f4 [Audio Output] Make toggling DSPs safe
The DSPs should not be deinitialized from another thread, possibly while
they are currently processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:16:21 -07:00
Christopher Snowhill
dd58a540a8 [FreeSurround] Add configuration option to enable
It now needs translation of the new string.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 03:02:08 -07:00
Christopher Snowhill
10272ca7a4 [Audio Processing] Increase thread stack size
Apparently, all these new changes with FreeSurround have pushed the
default 512KB thread stack size to the limit. And I'm not even using
stack variables, really, except for maybe the autoreleasepools.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:42:21 -07:00
Christopher Snowhill
7de0792b97 [FreeSurround] Actually make it work
Apparently, the LFE channel is not being initialized at all if bass
redirection isn't enabled, and even if it is, it's uninitialized for a
great portion of the spectrum. Clear it all on every iteration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:41:06 -07:00
Christopher Snowhill
eb0c1a8463 [Audio Output / Debugging] Fix sample logging
Fix the sample logging function that is optionally compiled into debug
versions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:39:25 -07:00
Christopher Snowhill
38832d9ce9 [Audio Processing] Update for new API
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 02:38:04 -07:00
Christopher Snowhill
b0bef40386 [FreeSurround] Change another variable to const
This should be const anyway, as it's not written to.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:47:02 -07:00
Christopher Snowhill
8b418004eb [FreeSurround] Further improvements
Still not working, though.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:47:02 -07:00
Christopher Snowhill
60429490b3 [FreeSurround] Fix surround block size
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>
2022-07-14 01:47:02 -07:00
Christopher Snowhill
11413ef3db [FreeSurround] The rest of the implementation
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>
2022-07-14 01:47:02 -07:00
Christopher Snowhill
85db95befd [FreeSurround] Experimental implementation code
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>
2022-07-14 01:47:01 -07:00
Christopher Snowhill
04d394c65c [Audio Processing] Move float32 converter
Move the Float32 converter to a different location, for any future plans
to support decoding audio files to common data for any other purpose.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:45:49 -07:00
Christopher Snowhill
58be4a40fc [FLAC Decoder] Change maximum buffer size
This should be more correct, especially considering that the library can
handle 32 bit files now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:43:33 -07:00
Christopher Snowhill
f4bbeaec77 [libFLAC] Remove debug overlay
There's a bug in the debug version of the library which does not occur
in the release build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 01:42:57 -07:00
Christopher Snowhill
27a1153b91 [FLAC Decoder] Correctly handle zero length frames
Apparently, the decoder is capable of returning zero length frames
without having hit the end of the stream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-14 00:01:59 -07:00
Christopher Snowhill
32ec11a42e Updated the help document a bit
Oops, it's been a while since I've touched this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 04:56:03 -07:00
Christopher Snowhill
30bff0b52d [Translations] Tweaked the Preferences dialog
Now the Preferences panels are 110 points wider, and most things are
shifted around in ways to make the current set of translations fit into
the dialogs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 04:37:16 -07:00
Christopher Snowhill
f17fc3708d [Polish translation] Fixed total time formatter
Please do not translate the token names, they are used by the code to
look up which value to insert into the string.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:50:34 -07:00
Christopher Snowhill
a9002a616e [Polish Translation] Fix the MainMenu strings file
The MainMenu.strings file had several mistyped quotation marks, and
several strings outside of quotation marks or comments, breaking the
menu translation entirely. This makes the translation actually work.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:43:08 -07:00
Christopher Snowhill
fc5c3c5441 [Polish translation] Activate localized strings
Template was missing from the project declaration. Oops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:42:08 -07:00
Christopher Snowhill
3adc30477d XIB touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 03:41:27 -07:00
Christopher Snowhill
c8c2bb909a [Ogg Vorbis/Opus] Fix tag clobber on play
Fixed the tags being overwritten by an "update" on non-streaming files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:12:35 -07:00
Christopher Snowhill
0fa2d0110c [Ogg Vorbis/Opus] Fix picture metadata handling
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-13 00:11:51 -07:00
Christopher Snowhill
13fb6bb141 [Playlist Insert] Add a special case for filtered
Insertions which occur when the playlist is filtered can try to add past
the end of the playlist. Let's try to dodge that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-12 23:47:03 -07:00
Christopher Snowhill
8d231d34d4 Update several of the dependencies
- Updated libFLAC to the latest Git commit, post 1.3.4.
- Updated libid3tag to 0.16.1.
- Updated libopus to the latest Git commit.
- Updated my FFmpeg libfdk-aac patch. Previously was overwriting
  memory when it was supposed to be skipping samples.

Also added debug versions of several of the libraries, and changed
the library extractor script to unpack the debug libraries over the
release set to add the particular matching debug versions when
building a debug build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-12 23:40:53 -07:00
LennyLip
4a5d21836a
Russian translation: new strings (#310)
* Update MainMenu.strings

* Update Preferences.strings
2022-07-11 19:58:58 -07:00
Christopher Snowhill
67f05bad27 [MAD Decoder] Fix streamed MP3s not working
Due to a change designed to stop playback when the end of the file is
reached, which should not be checked for unseekable files, which are
web streams that only stop when the connection drops, or when the user
stops playback manually.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:44:19 -07:00
Christopher Snowhill
fc1a226791 [HTTP Reader] Fix reading small static files
The reader was previously returning a failure state on open if the read
completed and fit entirely into the read buffer, which broke most remote
M3U or PLS playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:44:19 -07:00
Christopher Snowhill
32940d3277 [Sandbox Broker] Only pop suggester for local URLs
Only pop up the path suggester and check on local file URLs, not remote
URLs, which shouldn't be checked, since they don't require sandbox
permission grants or bookmarks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:44:19 -07:00
Christopher Snowhill
749e92694e Update About Window logo
The previous version was from an old render. Also apply some minor
tweaks to the scene.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:44:19 -07:00
Christopher Snowhill
a81ed64915 [Shuffle] Fix Shuffle Album mode
Oops, I should have remembered that the data structure changes would
break this search predicate. Now apply the search predicate to the
playlist representation, which allows searching against the data blocks
using the PlaylistEntry property implementation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 19:44:19 -07:00
70db08cf07
Update README.md
Third's the charm.
2022-07-11 19:10:50 -04:00
2619eff6ad
Update README.md 2022-07-11 19:09:46 -04:00
847f96c13e
Update README.md 2022-07-11 19:09:13 -04:00
af8cfc1c02
Added Lokalise logo and instructions. 2022-07-11 19:08:25 -04:00
Christopher Snowhill
7763269af8 Add missing strings to new translations
Still in need of translation from their respective authors.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 15:26:25 -07:00
LennyLip
7504300d9e Russian lang fixes 2022-07-11 15:19:25 -07:00
LennyLip
0ac17fe543 Russian translation 2022-07-11 15:19:20 -07:00
Christopher Snowhill
26f903ab77 Fix missing Polish declarations in project
There were still missing things.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 15:03:19 -07:00
Christopher Snowhill
8244eb0bb8 Activate Polish translation
The declarations for the translation were missing from the project files
so that it wasn't being used. Also added the missing strings to the
files that were already added to the translation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:40:32 -07:00
Christopher Snowhill
18824e0e18 [Visualization Controller] Minor guard check
Guard check in case visualization controller is called before any data
is posted to it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:39:23 -07:00
Christopher Snowhill
9f03b72b69 [Headphone Filter] Minor changes
Change a variable type, to avoid a warning.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-11 14:38:52 -07:00
Christopher Snowhill
8d8b508d09 [Audio Converter] Minor change for format changes
This should also seal up any potential hole for problems if there's an
audio format change and no audio buffered.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:36:31 -07:00
Christopher Snowhill
f8a8a57cf0 [Audio API] Repair the damage to the input chain
The input chain could hang up indefinitely, and MAD decoder didn't
indicate end of file properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 16:24:21 -07:00
pax
e595dbd525 first(really basic) open url panel translation. 2022-07-10 15:23:45 -07:00
pax
f5aa7401b6 translated equalizer strings, as well as the spotlight thing. 2022-07-10 15:23:45 -07:00
Christopher Snowhill
3c351f6968 [Input API] Change input readAudio method
readAudio now returns an AudioChunk object directly, and all inputs have
been changed to accomodate this. Also, input and converter processing
have been altered to better work with this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:14:47 -07:00
Christopher Snowhill
8bc9738ccb [Downmixer] Only downmix to stereo if not stereo
When downmixing to mono, only downmix to stereo first if the source is
not already stereo.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:08:56 -07:00
Christopher Snowhill
000a2e0cb6 [Project Files] Change most to enable modules
Most projects needed to be changed to enable C or Objective C modules.
Hopefully, this improves debugging.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 15:07:39 -07:00
Christopher Snowhill
abd557943c [Cuesheet Input] Don't repeatedly open file
The input file has already been opened for decoding by an earlier step
in the testing process, reuse the decoder from that. Spares a decoder
open cycle on all embedded cuesheet supporting formats.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-10 14:57:22 -07:00
Christopher Snowhill
39d3f7edfe [HRTF] Force filtering of odd channel formats
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>
2022-07-09 18:42:38 -07:00
Christopher Snowhill
57719a038c [HRTF] Reverse Z axis of speakers above listener
Apparently, positive elevation is above, negative is below.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 18:42:32 -07:00
Christopher Snowhill
0e1bf0abf2 Update some strings from Polish translation
Update missing strings, including one which was translated already in
the comments.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 16:22:06 -07:00
f2b9d9d84e [Spanish Translation] New strings
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-09 16:16:55 -07:00
bfd363df5d [Translation] Privacy policy URL can now be loaded from strings files
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-09 16:16:55 -07:00
Christopher Snowhill
30789c608e Add two missing strings from the Sparkle branch
Oops, those were missing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-09 16:16:55 -07:00
a7290aedee [Spanish Translation] Updated string for new HRTF filter. 2022-07-09 16:16:55 -07:00
Christopher Snowhill
349ab57afe Implemented all new HRTF filter
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>
2022-07-09 16:16:55 -07:00
pax
85d46bc1b3 The Polish translation is mostly ready. 2022-07-09 15:56:02 -07:00
pax
f682378cf7 *added Polish translation, not fully ready, but there ya go. 2022-07-09 15:56:02 -07:00
Christopher Snowhill
291b1e1253 Truncate text in playlist to a reasonable length
1024 characters aught to be enough for any playlist view.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:34:50 -07:00
Christopher Snowhill
02f49093a3 Remove the meta string cache
It wasn't helping anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:34:50 -07:00
564a8739d0 [Spanish Translation] Added strings for new Info Inspector fields 2022-07-08 16:34:50 -07:00
Christopher Snowhill
dad9275a30 Ditch the data compression
It just wasn't working out.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:34:50 -07:00
Christopher Snowhill
6222e25adc Experimental tag support redesign
This redesign completely changes how tags are stored in memory. Now all
arbitrary tag names are supported, where possible. Some extra work will
be needed to support arbitrary tags with TagLib, such as replacing it
with a different library.

Translation pending for a couple of strings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:34:50 -07:00
Christopher Snowhill
bea7d8e651 [Playlist] Increase default font size to Regular
Regular control size ends up being 13 points, rather than the previous
default of Small control size, which ended up being 11 points.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 17:56:47 -07:00
Christopher Snowhill
39ab0eaf45 Updated VGMStream to r1745-58-g828c6b09
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:44:01 -07:00
Christopher Snowhill
b29d19966f [Path Suggester] Only process local file URLs
Playlist entries for non-file URLs should be ignored.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:38:56 -07:00
Christopher Snowhill
63ca187aa7 [Table Views] Add a safety check to cell creation
Cell creation may create some other type of view, somehow. No idea how.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-07 16:38:48 -07:00
Christopher Snowhill
da053d7282 [File Tree] Significantly improve the watcher
- Switch to fine grained folder and file watching responses
- Navigate the PathNode tree using a fast dictionary of path components
- Quickly refresh the file tree by locating parent nodes to refresh

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 22:39:47 -07:00
Christopher Snowhill
1c3717eb84 [File Association] Correctly play files on open
When opening files from external association, such as opening files, or
opening folders with Cog, correctly obey the configured clear and play
or enqueue and play actions, by playing the new additions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 17:04:15 -07:00
Christopher Snowhill
a03e519c61 [Playlist Loader] Fix Clear and Play action
Clear and Play was broken by the previous update. This fixes it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 16:04:03 -07:00
Christopher Snowhill
2754a9fca3 [CI Scripts] Update to use command -v
Instead of `which`.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 14:44:36 -07:00
Christopher Snowhill
b4e3c05c87 [Playlist Loader] Load files in the background
Load new playlist entries in the background, asynchronously.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 14:28:14 -07:00
Christopher Snowhill
c54062f4bf Attempt for one last time to fix Xcode Cloud
This should hammer fix it. That'll show them for forcing a shallow
commit on me.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:37:59 -07:00
Christopher Snowhill
016bc9a45b Attempt to fix Xcode Cloud again
This time, run the git fetch tags and genversion in the pre
xcodebuild script.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:22:26 -07:00
Christopher Snowhill
df74f5ebe7 Fix Xcode Cloud CI script to fetch tags
The script needs to fetch repository tags to function properly.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 04:14:24 -07:00
Christopher Snowhill
333392f284 Change Crashlytics symbol upload script
Script should not fail an otherwise successful build.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 03:38:42 -07:00
Christopher Snowhill
c48d55ba9a [Playback] Prevent erroneous file from repeating
Prevent Repeat Single from locking up the player on an unplayable file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 02:20:05 -07:00
Christopher Snowhill
6ee0d8a267 [Sandbox Broker] Greatly speed up path resolving
The fragment remover need not detect whether the given path is a folder
or a file, as it is only removing hash marked fragments, not actually
removing the entire filename if it's only a file and not a folder like
the old versions used to. This greatly speeds up access, especially on
network shares.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:04:58 -07:00
Christopher Snowhill
d834819f79 [Path Config] Allow multiple selection
This more easily allows removing multiple paths at once.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:04:52 -07:00
Christopher Snowhill
60964a00b2 [Path Config] Remove exact items by token id
Should use the exact token object to remove them, rather than doing a
path comparison.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-06 00:04:45 -07:00
Christopher Snowhill
d03fb11f4c [Path Config] Properly prune the database
When cleaning up the path list, actually remove the pruned entries from
the Core Data storage, so they don't end up resolving to broken
bookmarks in the player, breaking playback on migrated configurations.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:47:05 -07:00
Christopher Snowhill
0e2bfeb671 [Path Config] Properly report broken bookmarks
Broken bookmarks weren't reporting as isStale, but rather, were failing
to resolve at all, and without this change, they were impossible to
detect in a migrated configuration.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:45:46 -07:00
Christopher Snowhill
ab285417ae [Album Art] macOS Ventura natively supports AVIF
Disable the compiled in AVIF support there, as the OS supports it
natively. Keep the libraries for older OSes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 23:44:35 -07:00
Christopher Snowhill
02e1276df8 [FFmpeg Decoder] Further improve Matroska tags
Matroska defaults the date field to "date_recorded".

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 18:11:45 -07:00
Christopher Snowhill
a8b13748d6 [FFmpeg Decoder] Better handle Matroska tags
Matroska files use the "TITLE" field for the album when there are
chapters. Also, Matroska container uses shorter gain field names for
album and track gain, differentiating them by either being global or
specific to each chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 17:40:57 -07:00
Christopher Snowhill
fadebd39ea [FFmpeg Decoder] Enable Metroska and WebM videos
Enable playback of video file extensions. Like other video formats
handled by the FFmpeg decoder, video streams are dropped in decode and
only the first audio stream is played.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 14:25:49 -07:00
6439c82eb6 [Spanish Translation] Updated strings in Appearance preferences
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-05 16:48:48 -04:00
Christopher Snowhill
472272129b [FLAC Decoder] Safety decoding for tag reader
Use tag string encoding guessing for tag decoding, just in case there
are invalid files with non-standard encoded strings inside the tags, or
if there are streams with such tags. We don't want any crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:44:44 -07:00
Christopher Snowhill
d4b434a68f [Spectrum] Enable switching style at runtime
It is now possible to switch the display style at runtime, while the
views are open.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:43:21 -07:00
Christopher Snowhill
f4926cf569 Interface builder touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 13:40:54 -07:00
Christopher Snowhill
d3256f3c54 Reformat spaces to tabs
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 12:52:53 -07:00
Dzmitry Neviadomski
0dc31808e7 Add preference to choose between SceneKit and DDB spectrum. 2022-07-05 12:49:09 -07:00
Christopher Snowhill
45ec7b6263 Greatly improve tag reading performance
Improve tag reading performance for Ogg, Opus, FLAC, TTA, and TAK, by
eliminating TagLib from the equation in those cases and just using the
respective file inputs to do the tag reading, which is apparently a lot
faster anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 00:55:48 -07:00
Christopher Snowhill
22cd16bb46 [Audio Player] Eliminate an avenue of lockups
Prevent the player from locking up in certain circumstances, by not
locking chainQueue the entire time this function is processing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-05 00:55:41 -07:00
Christopher Snowhill
42b2142ab7 Remove unnecessary files from build and copy steps
Remove a single .inc include from CogAudio build phase, as it's included
but not compiled as Pascal like Xcode thinks. Also remove a bunch of
files from being copied into the resulting .framework and .bundle files
during link stage, as we don't need to distribute that stuff.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 23:58:06 -07:00
Christopher Snowhill
2c698304ca [Playlist Loader] Revert background loader
This reverts most of 802a86a3d8, since it
didn't work anyway.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 18:09:01 -07:00
Christopher Snowhill
af82399f37 [Playlist Loader] Fix background queue post action
Post action now returns the files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-04 17:37:32 -07:00
Christopher Snowhill
1145bca042 [Equalizer] Fix support for arbitrary channels
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>
2022-07-03 22:40:40 -07:00
Christopher Snowhill
e6c3fcaa0d [Equalizer] Remove unnecessary code
This code is obsolete, remove it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:40:33 -07:00
Christopher Snowhill
3c86758cb5 [Sandbox] Ask for permission for container folders
Ask for permission to access the folders containing container files,
such as .CUE sheets, or .M3U or .PLS playlists.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 22:40:26 -07:00
Christopher Snowhill
b3e0da6fe9 [M3U Playlist] Reformulate safety checks
Apparently someone managed to crash this with their playlists. No idea
how. Added more safety checks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-03 14:30:29 -07:00
Christopher Snowhill
7f1c337ee8 [Tag Reading] Moved external cover art reader
Moved external cover art reader to a place where it can be used for any
format, even formats unsupported by Metadata Reader interfaces.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 14:59:47 -07:00
Christopher Snowhill
b72d5a4c26 Update Info.plist.template
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:37:32 -07:00
Christopher Snowhill
a32a8718d7 [Plugin Loader] Unregister loader callback
This callback should be unregistered when plugin loading completes,
otherwise we could end up processing bundles loaded by external stuff,
like Audio Units loading for MIDI playback.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:31:22 -07:00
Christopher Snowhill
9839f51ee1 [FFmpeg Input] Add .m4b and .m4r extensions
Add support for more file name extensions, so we don't fall back on
Core Audio Input for these files.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:22:34 -07:00
Christopher Snowhill
74bb2527a9 [FFmpeg Input] Implement SoundCheck tag support
Implement support for the Sound Check tag format.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:21:28 -07:00
Christopher Snowhill
cfcb7c041d [TagLib] Disable MP4 tag reader, as it can crash
This MP4 tag reader is buggy. Disable it in favor of FFmpeg decoder's
metadata reader.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 04:20:01 -07:00
Christopher Snowhill
a847cbde3b [MIDI Input] No longer crash when seeking to the end
When seeking to the end of a file, no longer crash due to out
of range std::vector access, because it was using at() with an
offset of the array size. Instead, offset from the begin()
iterator return value, which allows offsetting to end().

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 03:19:24 -07:00
321e3382f4 [Spanish Translation] Added new strings for synthesis settings
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-02 01:25:24 -07:00
Christopher Snowhill
b025a21e13 [Synthesizers] Implement default overrides
Default time, fade, loop count, and sample rate may now be overridden.

Synchronized preferences strings tables. Spanish translation of new
options pending, new releases won't be pushed until they're complete.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-02 01:25:24 -07:00
Christopher Snowhill
34513f3b38 [Translation] Widen the Path Suggester column
Widen the enable column, for the Spanish description of the column
header.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:31:16 -07:00
Christopher Snowhill
cb007d62a1 [Translation] Fix translation of Path Suggester
Also fix the fact that the XIB wasn't embedding the XIB/NIB in the app
as a result of the translation move.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 14:31:10 -07:00
Christopher Snowhill
a53a8ecb82 [Audio Output] Fix equalizer support
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>
2022-07-01 14:11:46 -07:00
Christopher Snowhill
70b01a7cf1 [Plugin Controller] Add Cue sheet safety check
If somehow a plugin doesn't load, skip cuesheet should skip it anyway,
as we don't want any recursive loops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 13:39:06 -07:00
Christopher Snowhill
99f15679a6 [Audio Output] Remove unnecessary variables
These variables weren't being used anyway, so remove them.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 12:42:21 -07:00
dd20073a9b [Translation] The Big Translation Commit
- Plugs the Total duration text to macOS's localization technology
- Adds a proper Spanish translation
- Adapts certain dialogs to make them more suitable for translation

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-07-01 12:37:30 -07:00
Christopher Snowhill
189999b7c2 [libOpenMPT] Remove unnecessary compile option
ENABLE_ASM isn't even used anywhere in the library any more.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 01:03:13 -07:00
Christopher Snowhill
904ce1c4cd Move all dialog XIBs for translation
Make it easier to translate the relevant dialogs now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:38:25 -07:00
Christopher Snowhill
c69433bf0b Updated credits file with Patron preference
Oops, missed that Patreon message, because Patreon did not email me.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:17:55 -07:00
Christopher Snowhill
23fa3c5e8e Update Credits.html in Spanish placeholder
Spanish translation really needs doing some time soon, maybe.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-01 00:12:03 -07:00
Christopher Snowhill
731e52c440 Build libOpenMPT from source once again
Bundle libOpenMPT as a dynamic framework, which should be safe once
again, now that there is only one version to bundle. Also, now it is
using the versions of libvorbisfile and libmpg123 that are bundled with
the player, instead of compiling minimp3 and stbvorbis.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 22:57:30 -07:00
Christopher Snowhill
919497148a Updated libOpenMPT to version 0.6.5-pre.1+r17609
This allows us to eliminate the requirement to continue bundling version
0.5.x of libOpenMPT for compatibility with macOS 10.13 through 10.14.x.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 21:28:28 -07:00
Christopher Snowhill
0832a8ea34 Restore the File Tree, now with a chooser button
Revert "Remove the file tree, as Sandbox does not permit"

This reverts commit 02ec735687.

This also changes how the File Tree choosing works.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 16:57:51 -07:00
Christopher Snowhill
830d3bf3be [Info Inspector] Improve formatting of sample rate
Sample rate now has a locale independent formatting, and no longer uses
scientific notation for large numbers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 00:28:03 -07:00
Christopher Snowhill
ff56b757e6 [Play Counts] Fix reporting play counts
Play counts are guaranteed to be reported on the correct track now.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 23:26:30 -07:00
Christopher Snowhill
608483ae60 Update libVGM and BASSMIDI, SF3 support
BASSMIDI now includes SF3 support, as well as several other changes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 23:25:59 -07:00
Christopher Snowhill
ee5b6be4bb [Sandbox] Synchronize write accesses to storage
Synchronize writing to the bookmark storage to the main thread.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 19:41:24 -07:00
Christopher Snowhill
ad7574be59 [Sandbox] Fix URL fragment removal function
This should be deleting from the #, including the #.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 19:41:20 -07:00
Christopher Snowhill
14a1157508 [Context Menu] Hook up Reset Play Counts item
Actually hook up the Reset Play Counts menu item so it actually does
something instead of just sitting there looking pretty.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:41:46 -07:00
Christopher Snowhill
7e2dda750e [Sandbox Config] Correctly test paths for files
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:11:22 -07:00
Christopher Snowhill
170310d7e5 [Sandbox] Remove startup folder consent prompt
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 12:02:59 -07:00
Christopher Snowhill
82179a5f10 [Sandbox] Support bookmarking individual files
Individually added files, directly opened by the user, may now store
bookmarks in settings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 11:56:50 -07:00
Christopher Snowhill
02ec735687 Remove the file tree, as Sandbox does not permit
The Sandbox does not permit such controls to exist.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 11:56:01 -07:00
06739eb001 [Info Inspector] Made fields selectable, and fixed blending issue with
album art

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-29 14:14:27 -04:00
bd8cfd300a [About Window] Fixed appearance for systems without Dark Mode
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-29 14:13:40 -04:00
Christopher Snowhill
3ef6a4204f [Sandbox] Handle file tree path config better
Handle the configuration better, by adding the path to the grants list
if it is newly configured.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-29 00:31:34 -07:00
Christopher Snowhill
f5bde75eda [Sandbox] Automatically save folder bookmarks
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 23:13:42 -07:00
Christopher Snowhill
6f126f4857 [Sandbox] Reduce entitlements granted by default
Since App Store approval decided these suddenly matter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 22:58:57 -07:00
Christopher Snowhill
22085d94f1 [Sandbox] Show grant dialog on launch if empty
If there are no configured paths, show the grant page on every startup.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 22:58:13 -07:00
Christopher Snowhill
de7afad3d4 [Playlist Loading] Process messages while loading
Process main queue messages by handling the loading in a background
queue, and sync it to the main thread periodically, while pausing to
wait for the results. This allows the file open dialog to return
immediately, and display loading progress on the status bar.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:26:55 -07:00
Christopher Snowhill
bf6a28a95e [Playlist View] Change ratings column to variable
The ratings column needs to be made variable width, for variable font
sizes. If anyone knows how to force the width to fit the current text,
I'm open to suggestions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:23:43 -07:00
Christopher Snowhill
e491de0a93 [Crash Handling] Enable exceptions for debugging
Debug builds should have exceptions enabled, rather than crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 20:22:51 -07:00
Christopher Snowhill
f5412fbfec [About Dialog] Add needed WebKit framework
This is needed for macOS older than 11.0? 10.15? to open the About
dialog without crashing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 04:28:33 -07:00
Christopher Snowhill
44fb1efc73 [Play Info] Implement track rating system
The track ratings are stored in the same stats table as the play counts.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:59:36 -07:00
Christopher Snowhill
2d7c3b51c7 [Audio Output] Restart correct track
When restarting playback on the current track, restart the correct
track, in case restarting near the end of it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:59:23 -07:00
Christopher Snowhill
8fc981cb92 [Play Counts] Add option to (mass) reset counts
Add option to reset counts for all selected tracks on the playlist.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:59:10 -07:00
Christopher Snowhill
de43192453 [Play Counts] Commit play count edits to storage
Was calling commitEditing rather than commitPersistentStore, whoops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:59:00 -07:00
Christopher Snowhill
0515a63645 Resource templates touched by Xcode
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:58:31 -07:00
Christopher Snowhill
3b1eefaabb [Play Counts] Track play counts of correct track
Track play counts for the correct track, even on short tracks. Also
correctly track the play count of the last played item in the play queue
which stops with bufferChain set to nil, so the previous iteration was
not tracking it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-28 01:57:00 -07:00
Christopher Snowhill
f1dd55b29e [File Tree] Pop permission grant on setting root
Setting the root path should now pop up a permission grant dialog.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 16:17:54 -07:00
Christopher Snowhill
9411e7bd45 [Sandbox Broker] Synchronize full access operation
Full access should be synchronized, otherwise rapid access to the same
path from different threads will cause crashes.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:56 -07:00
Christopher Snowhill
dc02404184 [Metadata Cache] Actually run cleanup thread
Previously, the cleanup thread was not being run. Also, only reset the
metadata deduplication store when the cache is first emptied.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:48 -07:00
Christopher Snowhill
bb11567948 [Audio Output] Change converter back to Obj-C
Change converter source file back from Objective-C++ to Objective-C.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-27 01:00:42 -07:00
Christopher Snowhill
cacdc13d15 [Sandbox Broker] Bypass entitled paths
Include entitlement granted user folders in the permission check, so
that if the file or folder is nested under one of them, it allocates a
static permission object, rather than querying the list of configured
paths every time. This also prevents the player from popping open the
path grant / suggester dialog every time a default path is in the file
set listed, which should provide some relief to most users.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 23:53:06 -07:00
Christopher Snowhill
824648321c Attempt to fix Xcode Cloud CI
Try to generate the Info.plist before xcodebuild runs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 23:00:18 -07:00
Christopher Snowhill
ee79935a8a Update versioning setup
Versioning now happens before building Cog itself, and goes
into the Info.plist in the project directory. The original
file became a template file which is altered any time a
build occurs.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 22:10:17 -07:00
Christopher Snowhill
b3591867e7
Update debug.yml
Switch to building on macos-12
2022-06-26 21:12:27 -07:00
Christopher Snowhill
bf03119373 Add Package.resolved back to repo
Guess we can't use Github actions now, because this file breaks those.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:27:09 -07:00
Christopher Snowhill
fc296bda77 Add CI scripts for Xcode Cloud
Add a post clone script for Xcode Cloud

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:23:40 -07:00
Christopher Snowhill
cc45750c0c Automatically unpack libraries before building
This required adding the included script in every project that links to
one of the bundled libraries. The script is designed to sleep for a
while if another thread is already extracting the libraries. The script
uses a temporary file as an extraction step lock, so other instances
sleep, and then detect the libraries.updated file, which is created
before the lock is removed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 20:12:06 -07:00
Christopher Snowhill
05960b1da1 Updated VGMStream to r1745-47-gfa55119d
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 15:12:00 -07:00
Christopher Snowhill
f516658a5e [Equalizer] Prevent crash on stop
Wait for the equalizer to be shut down properly by the main thread
before destroying it. Otherwise, the main thread could crash on stop,
due to accessing the equalizer handle while it's being torn down in the
output thread.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 14:48:02 -07:00
Christopher Snowhill
db181bde4d [Visualization System] Change API a bit
Now the API makes both PCM and FFT data optional, and will do nothing if
neither are requested. Also, it now supports a latency offset in seconds
with floating point precision. The two built-in visualizations currently
request zero larency. Increasing the latency asks for even older samples
while specifying a negative count requests samples from the "future"
relative to what the listener is hearing.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 05:40:06 -07:00
Christopher Snowhill
8068a506b9 [Play Events] Don't bug on end of playlist
Don't bug out on end of playlist, when didBeginStream will receive a nil
track pointer, which should result in unsetting the current track in the
player, and not send a DidBegin notification to everything, including
the visualization views' event handlers.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 05:40:00 -07:00
Christopher Snowhill
5c4cfb4053 [Play Counts] Fix counts for tracks with subsongs
Fix counts for tracks with subsongs from piling all the counts onto the
first subsong seen, by using the URL fragment in the filename check and
storage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 04:38:18 -07:00
Christopher Snowhill
f04761ff42 [Audio Output] Fix for previous commit
This fixes the problem caused by the following commit:

050aaaf852

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:58:10 -07:00
Christopher Snowhill
adbf8aa7d1 Fix compilation
Oops, that last suggester change broke compilation.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:08:39 -07:00
Christopher Snowhill
1e03df2aab [Sandbox] Don't try to grant access to container
Do not try to grant access to the app's container folder when searching
for paths to add.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 03:00:00 -07:00
Christopher Snowhill
0e4ff8a55c [Sandbox] Compare to the actual user paths
Remove the sandbox reference, because the user will add folders outside
the sandbox, and we have entitlements to access these folders.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:59:49 -07:00
Christopher Snowhill
bc309fe725 [Sandbox] Suggest URLs that are contained in CUEs
Cuesheets can now expose which URLs they contain, which may help with
sandbox path configuration. That is, if the CUE sheets are already
readable.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-26 02:59:37 -07:00
Christopher Snowhill
378f710cee [Visualization] Resample more audio if present
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>
2022-06-26 02:59:27 -07:00
Christopher Snowhill
aa3673ed33 [Audio Output] Better handle latency oddities
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>
2022-06-26 02:59:20 -07:00
Christopher Snowhill
c489d7ca91 [Audio Output] Play last track and stop correctly
Play last track up until it actually ends, and stop on command.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:43:16 -07:00
Christopher Snowhill
99fad892f0 [FFmpeg Decoder] Don't post redundant meta event
Don't post a metadata event on open, because inputs will relay it to the
player as an early notification bubble, which is unwanted.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 06:05:35 -07:00
Christopher Snowhill
8d10aa7e80 [Audio Output] Fix serious memory leakage
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>
2022-06-25 06:00:34 -07:00
Christopher Snowhill
f2dee9e0a7 [fdkaac] Update libfdk-aac to 2.0.2 with patches
Update fdk-aac library in dependencies package.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:14:09 -07:00
Christopher Snowhill
a1a084aabb [Audio Output] Fix serious deadlock issue
There was a serious deadlock issue. Now it is fixed. Whew.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:14:04 -07:00
Christopher Snowhill
cca447ca5e [InputNode] Syntax code fix
This code was misformatted.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 05:13:57 -07:00
Christopher Snowhill
4bc4b38489 [Play Count Info] Tabulate first seen info later
Tabulate first seen information when loading the metadata, rather than
when first adding the tracks to the playlist. This should fix first seen
information when metadata is available, as the information will be
useless without track titles.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:40:49 -07:00
Christopher Snowhill
ed8c8acc89 [Cuesheet] Greatly improve loading performance
Cuesheets were invoking a seek operation on open, rather than on first
playback, and this has a heavy toll on FFmpeg audio formats, apparently.
Defer the initial seek to the first readAudio call, and do not invoke it
if a seek was already called on that input session.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:40:43 -07:00
Christopher Snowhill
b3be8f9d11 [FFmpeg] Fix chapter handling and seeking
Fix chapter startup, and chapter seeking.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 02:40:36 -07:00
Christopher Snowhill
3852fab64b [FFmpeg] Seek including skip samples
This is essential for chapters, as otherwise, we would be skipping an
awful lot of samples every chapter, or every seek within a chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 01:43:57 -07:00
Christopher Snowhill
65fd9c71c6 [FFmpeg] Support files with chapters
Support file chapters, including metadata reading for each chapter.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 01:35:34 -07:00
Christopher Snowhill
43c709cd9f [FFmpeg] Deduce the length from the container
Determine the length of the file from the container, rather than the
individual audio stream. The former is more likely to be set than the
latter is.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:54 -07:00
Christopher Snowhill
a6b6c8120b [FFmpeg] Update FFmpeg library and decoder plugin
Update based on newest changes from upstream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:41 -07:00
Christopher Snowhill
d79275b285 [Audio Output] Correctly configure WAVE layouts
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>
2022-06-25 00:07:31 -07:00
Christopher Snowhill
27924e246d [Audio Output] Correctly delay layout updates
Channel layout updates should be delayed when resampling, just like
sample format changes are.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:20 -07:00
Christopher Snowhill
94de049184 [FFmpeg] Update minimum platform for x86_64
Update minimum platform version to macOS 10.13.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:07:04 -07:00
Christopher Snowhill
43180640f2 [FFmpeg] Enable TrueHD decoder and demuxer
Oops, somehow I didn't enable TrueHD support.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:06:54 -07:00
Christopher Snowhill
67b6a3606f [FFmpeg] Update libfdk-aac fixed point patch
Update this patch to the latest FFmpeg master source, and update to use
fmtconvert instead of a naive for loop.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-25 00:06:48 -07:00
Christopher Snowhill
d563617998 [Audio Output] Stop immediately, and fix deadlocks
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>
2022-06-24 19:14:48 -07:00
Christopher Snowhill
6592144584 [Vorbis / Opus] Do not assume text encoding
Stream metadata encoding may not be UTF-8, even though the Vorbis
Comment specification clearly calls for this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 19:12:38 -07:00
Christopher Snowhill
26ac2b09fb Move static and dynamic libaries to archive
Please remember to unpack the archive before building, and
if it is updated by a future version.
2022-06-24 17:09:29 -07:00
Christopher Snowhill
156e25ed6a [Sandbox] Change preference dialog descriptions
Make the descriptions more apt to what they do.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:09:25 -07:00
Christopher Snowhill
f9490c1329 [OpenMPT / OpenMPT Legacy] Fix include paths
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:09:21 -07:00
Christopher Snowhill
93736565cb [mpg123] Fix include paths 2022-06-24 17:09:15 -07:00
Christopher Snowhill
431849414f [Sandbox Broker] Fix deadlock and crash
The crash was because we weren't copying the results array before
iterating over it, and the deadlock was because this was forced to go
through the main thread, rather than going through its calling thread,
which could lock up if the main thread was busy working with the Sandbox
Broker object.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:09:11 -07:00
Christopher Snowhill
ec91f61403 [Metadata] Commit first seen date for whole batch
Commit only once the entire batch is loaded and processed. Also commit
using the correct function.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:09:06 -07:00
Christopher Snowhill
32a595222d [OpenMPT / vgmstream] Made libraries pre-built
Made the OpenMPT / legacy OpenMPT and mpg123 libraries pre-built.
Changed the OpenMPT and vgmstream plugins to import the libraries as
they are now. Made mpg123 embedded and imported by the main binary,
since it's now shared by two plugins.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:09:02 -07:00
Christopher Snowhill
4540b88094 [Sandbox Broker] Copy results array
Hopefully this heads off a crash elsewhere.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 17:08:57 -07:00
Christopher Snowhill
0cc084b58b [Audio Output] Properly handle end of playlist
Handle audio on the end of the playlist, flushing playback until all
output stops.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:41 -07:00
Christopher Snowhill
858f446597 [Audio Output] Synchronize access, report latency
Report resampler latency properly, and synchronize access to the
resampler objects.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:33 -07:00
Christopher Snowhill
3a9db65b53 [Visualization] Resample all visualizer audio
Visualizer audio is now resampled to 44100 Hz, for consistency across
the system.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:27 -07:00
Christopher Snowhill
2e45deb8d3 [Audio Output] Resample unsupported sample rates
These rates are too high for Apple's output routines, for some reason.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 03:47:19 -07:00
Christopher Snowhill
6d772562ca [Core Data Store] Fix startup playlist pruning
The playlist was being pruned of entries marked for deletion, but they
were not being pruned from the set that was then added to the player.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 00:52:33 -07:00
Christopher Snowhill
ba33218ddf [Path Suggester] Automatically pop where required
The Path Suggester will now automatically open when new files are added
to the playlist and a given path is not in the sandbox settings. It will
also pop for both the File Tree and MIDI SoundFont path configuration
settings being changed.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 00:52:03 -07:00
Christopher Snowhill
b6621da410 [Sandbox Broker] Synchronize storage access
Synchronize storage access to main thread only, to prevent enumeration
from hitting a case of the main thread writing to the storage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-24 00:46:45 -07:00
280b58dfd8 [Sandbox] Fixed path suggester window
Added a title to the window, make the table view resize properly, and
remove the font size inheritance from the main window.

Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-23 23:25:29 -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
2c2a058126 Cog now requires macOS 10.13 as a minimum version
All optional fallback code for older versions has also been removed, and
everything now assumes 10.13.0 or newer. Some cases are still included
for point releases, such as 10.13.2.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-23 23:23:07 -07:00
Christopher Snowhill
27b2e8584d Updated VGMStream to r1745-37-g776c4d8c
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:33:06 -07:00
Christopher Snowhill
b2c354a32c Serialize persistent store update to main thread
This needs to be called on the main thread, as something may or may not
be enumerating over the data while this thread decides to call it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:11:06 -07:00
Christopher Snowhill
6867ef1e9a [Playlist Info Loader] Do not clear if loading
Do not clear the progress indicator if a loading task is already running
in the background, but instead return without doing anything.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 19:06:10 -07:00
Christopher Snowhill
71d8cb6246 Comply with App Store policies
Remove the stale Updates check preferences pane, and remove the donation
option from the menu, as it is considered In App Purchases.

Consider adding actual App Store In App Purchase options of "Buy me a
coffee" or similar, with no guarantee of return for the purchase, other
than furthering development. Make them repeatable purchases.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-22 16:27:51 -07:00
5e6c0a4c52
[About Window] Fix
Pull request #281 by @nevack.
2022-06-22 18:39:36 -04:00
e46dc12efc [About Window] Reorganized credits and added @nevack and myself in them
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-22 18:38:14 -04:00
Dzmitry Neviadomski
45345b810c Fix runtime warnings in Window/AboutWindowController.xib
Fix typo in File Owner class name and remove absent outlet.
2022-06-23 01:34:17 +03:00
9c371b8181
Merge pull request #280 from losnoco/nevack/about-window
AboutWindow adjustments
2022-06-22 18:28:54 -04:00
Dzmitry Neviadomski
43467b6978 AboutWindow adjustments
Allow opening links in default browser
Close window on Esc
Add rounded corners
2022-06-22 19:01:42 +03:00
Christopher Snowhill
05eb1c38a0 Changed updater script to handle new version strings
New version strings are in a different place, and Sparkle will no longer
be including the Git hash in the CFBundleVersion query, so we must get
it from the ZIP filename.
2022-06-22 01:17:02 -07:00
Christopher Snowhill
90b064fd3a Empty commit to sync version number 2022-06-21 23:52:21 -07:00
Christopher Snowhill
5cd39b919b Update README to add App Store information
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:51:50 -07:00
Christopher Snowhill
4db0fc1f5f One last attempt to fix CI
This should fix building. I don't know how I missed those.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:50:12 -07:00
Christopher Snowhill
73ad7901b0 Assign blank development team in project files
Hopefully this blank assignment will spare these files from being
touched by Xcode again in the future, when the variable in question is
imported from a developer supplied configuration file.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:29:17 -07:00
Christopher Snowhill
d3e069ddc0 Remove developer supplied configuration file
This file should not be referenced directly by projects, otherwise it
will be expected to exist, even in CI.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 23:29:07 -07:00
Christopher Snowhill
4a0d4bb093 [Volume Control] Only initialize view once
Only initialize viewController once, the first time the volume control
is opened. Re-initializing it can cause an error assigning it as first
responder to the volume slider popover view.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 22:52:52 -07:00
Christopher Snowhill
60523b985a Completely overhaul code signing practices
Redesign the code signing from the ground up. Now all bundles and their
embedded frameworks import the Shared.xcconfig file and enable its
settings, so they may be signed with Apple Development instead of sign
to run locally. This apparently isn't necessary for frameworks which are
embedded in the main app bundle directly, only for the bundles and their
frameworks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 22:43:04 -07:00
Christopher Snowhill
82a1a400d9 Remove deep forced code signing option
This option should no longer be needed for anything.
2022-06-21 19:39:36 -07:00
d78b31d34e [Main Menu] Added Privacy Policy link in App Menu
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-21 22:30:30 -04:00
0679b146a3 [About Dialog] Switched to WebView for credits
Signed-off-by: Kevin López Brante <kevin@kddlb.cl>
2022-06-21 22:20:18 -04:00
Christopher Snowhill
2821cb36b5 [Crashlytics] Require asking user consent
Require asking user consent for data transmission on first launch, or
otherwise disable sending crash reports by default.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 19:03:37 -07:00
Christopher Snowhill
eadac4c033 [Info Plist] Auto format XML escapes
Automatically format any XML escapes of file type association names.
Adjust Info.plist to account for this change.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-21 18:59:57 -07:00
179 changed files with 30 additions and 7845 deletions

View file

@ -67,11 +67,6 @@
- (IBAction)delEntries:(id)sender;
- (IBAction)savePlaylist:(id)sender;
- (IBAction)openLiberapayPage:(id)sender;
- (IBAction)openPaypalPage:(id)sender;
- (IBAction)openKofiPage:(id)sender;
- (IBAction)openPatreonPage:(id)sender;
- (IBAction)privacyPolicy:(id)sender;
- (IBAction)feedback:(id)sender;
@ -113,8 +108,6 @@
- (IBAction)showRubberbandSettings:(id)sender;
+ (void)globalShowRubberbandSettings;
- (IBAction)checkForUpdates:(id)sender;
@property NSWindow *mainWindow;
@property NSWindow *miniWindow;

View file

@ -30,8 +30,6 @@
#import <MASShortcut/Shortcut.h>
#import <MASShortcut/MASDictionaryTransformer.h>
#import <Sparkle/Sparkle.h>
#import "PreferencesController.h"
#import "FeedbackController.h"
@ -44,22 +42,6 @@ BOOL kAppControllerShuttingDown = NO;
static AppController *kAppController = nil;
@interface SparkleBridge : NSObject
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController;
@end
@implementation SparkleBridge
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController {
static SPUStandardUpdaterController *sharedStandardUpdaterController_ = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedStandardUpdaterController_ = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate: nil userDriverDelegate: nil];
});
return sharedStandardUpdaterController_;
}
@end
@implementation AppController {
BOOL _isFullToolbarStyle;
}
@ -195,12 +177,6 @@ static BOOL consentLastEnabled = NO;
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.sentryConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
#ifdef DEBUG
// Prevent updates automatically in debug builds
[[[SparkleBridge sharedStandardUpdaterController] updater] setAutomaticallyChecksForUpdates:NO];
#endif
[[[SparkleBridge sharedStandardUpdaterController] updater] setUpdateCheckInterval:3600];
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
[self.infoButton setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")];
@ -617,22 +593,6 @@ static BOOL consentLastEnabled = NO;
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}
- (IBAction)openLiberapayPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://liberapay.com/kode54"]];
}
- (IBAction)openPaypalPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.com/paypalme/kode54"]];
}
- (IBAction)openKofiPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://ko-fi.com/kode54"]];
}
- (IBAction)openPatreonPage:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.patreon.com/kode54"]];
}
- (IBAction)privacyPolicy:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:NSLocalizedString(@"PrivacyPolicyURL", @"Privacy policy URL from Iubenda.")]];
}
@ -664,6 +624,9 @@ static BOOL consentLastEnabled = NO;
NSNumber *fontSize = @(fFontSize);
[userDefaultsValuesDict setObject:fontSize forKey:@"fontSize"];
NSString *feedURLdefault = @"https://cogcdn.cog.losno.co/mercury.xml";
[userDefaultsValuesDict setObject:feedURLdefault forKey:@"SUFeedURL"];
[userDefaultsValuesDict setObject:@"enqueueAndPlay" forKey:@"openingFilesBehavior"];
[userDefaultsValuesDict setObject:@"enqueue" forKey:@"openingFilesAlteredBehavior"];
@ -705,6 +668,18 @@ static BOOL consentLastEnabled = NO;
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
[[NSUserDefaults standardUserDefaults] synchronize];
// And if the existing feed URL is broken due to my ineptitude with the above defaults, fix it
NSSet<NSString *> *brokenFeedURLs = [NSSet setWithObjects:
@"https://kode54.net/cog/stable.xml",
@"https://kode54.net/cog/mercury.xml"
@"https://www.kode54.net/cog/mercury.xml",
@"https://f.losno.co/cog/mercury.xml",
nil];
NSString *feedURL = [[NSUserDefaults standardUserDefaults] stringForKey:@"SUFeedURL"];
if([brokenFeedURLs containsObject:feedURL]) {
[[NSUserDefaults standardUserDefaults] setValue:feedURLdefault forKey:@"SUFeedURL"];
}
NSString *oldMidiPlugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"];
if(oldMidiPlugin) {
[[NSUserDefaults standardUserDefaults] setValue:oldMidiPlugin forKey:@"midiPlugin"];
@ -992,10 +967,6 @@ static NSDictionary *shortcutDefaults = nil;
[kAppController showRubberbandSettings:kAppController];
}
- (IBAction)checkForUpdates:(id)sender {
[[SparkleBridge sharedStandardUpdaterController] checkForUpdates:[[NSApplication sharedApplication] delegate]];
}
- (void)selectTrack:(id)sender {
PlaylistEntry *pe = (PlaylistEntry *)sender;
@try {

View file

@ -1531,11 +1531,6 @@
<action selector="showWindow:" target="Hd4-Wy-Rfl" id="xfd-8T-SL4"/>
</connections>
</menuItem>
<menuItem title="Check for Updates..." id="302">
<connections>
<action selector="checkForUpdates:" target="226" id="jEY-i9-qwZ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="1100">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
@ -1546,45 +1541,6 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="0ig-xg-gkg"/>
<menuItem title="Donate" id="751">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Donate" id="kue-p2-G0Y">
<items>
<menuItem title="LiberaPay" id="nyW-nI-abw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openLiberapayPage:" target="226" id="pS6-Hj-tIm"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Mbf-yW-WGC"/>
<menuItem title="One time" enabled="NO" id="wLp-NA-5u2">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="PayPal" id="xcs-tx-Viz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openPaypalPage:" target="226" id="oxr-P1-35O"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="txC-Jd-Gez"/>
<menuItem title="Recurring" enabled="NO" id="iRb-7e-iMC">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Ko-fi" id="CVM-rp-UJe">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openKofiPage:" target="226" id="gax-6q-SuW"/>
</connections>
</menuItem>
<menuItem title="Patreon" id="NXj-oA-q3F">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openPatreonPage:" target="226" id="LFz-4J-b6o"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Send Feedback..." id="303">
<connections>
<action selector="feedback:" target="226" id="GSH-G5-qM1"/>

View file

@ -2,11 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spks</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spki</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>

View file

@ -150,8 +150,6 @@
838A33832D06CF4100D0D770 /* SpectrumViewCG.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33802D06CF4100D0D770 /* SpectrumViewCG.m */; };
838A33842D06CF4100D0D770 /* SpectrumWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33822D06CF4100D0D770 /* SpectrumWindowController.m */; };
838A33872D06CFCA00D0D770 /* SpeedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33862D06CFCA00D0D770 /* SpeedButton.m */; };
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; };
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; };
839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; };
839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; };
@ -733,7 +731,6 @@
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */,
8305963C277F013200EBFAAE /* File_Extractor.framework in CopyFiles */,
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */,
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */,
17F561400C3BD4F30019975C /* CogAudio.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -988,7 +985,6 @@
838EE79E29A8556000CD0580 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
838EE7A029A8556500CD0580 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; };
838F851D256B4E5E00C3E614 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Frameworks/Sparkle.framework; sourceTree = "<group>"; };
83922FB6286B1AA900A0B039 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
839614A1286ED97200D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; };
839614A4286ED98600D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
@ -1088,7 +1084,6 @@
838A33742D06A9B100D0D770 /* librubberband.3.dylib in Frameworks */,
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */,
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */,
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
@ -1134,7 +1129,6 @@
isa = PBXGroup;
children = (
ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */,
838F851D256B4E5E00C3E614 /* Sparkle.framework */,
17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
);

0
Plugins/Organya/fx96.pxt Normal file → Executable file
View file

0
Plugins/Organya/fx97.pxt Normal file → Executable file
View file

0
Plugins/Organya/fx98.pxt Normal file → Executable file
View file

0
Plugins/Organya/fx99.pxt Normal file → Executable file
View file

0
Plugins/Organya/fx9a.pxt Normal file → Executable file
View file

0
Plugins/Organya/fx9b.pxt Normal file → Executable file
View file

0
Plugins/Organya/wavetable.dat Normal file → Executable file
View file

View file

@ -17,7 +17,6 @@
<outlet property="outputPane" destination="57" id="75"/>
<outlet property="playlistView" destination="231" id="244"/>
<outlet property="rubberbandPane" destination="l4Y-NE-ezS" id="XTA-io-tov"/>
<outlet property="updatesView" destination="50" id="99"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
@ -305,24 +304,6 @@
</subviews>
<point key="canvasLocation" x="-151" y="-18.5"/>
</customView>
<customView id="50" userLabel="UpdatesView">
<rect key="frame" x="0.0" y="0.0" width="640" height="56"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="51">
<rect key="frame" x="18" y="19" width="602" height="18"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="check" title="Automatically check for updates on startup" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="207">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.SUCheckAtStartup" id="53"/>
</connections>
</button>
</subviews>
<point key="canvasLocation" x="-151" y="145"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="52" userLabel="Shared Defaults"/>
<customObject id="57" userLabel="OutputPane" customClass="OutputPane">
<connections>

View file

@ -26,7 +26,6 @@
IBOutlet RubberbandPane *rubberbandPane;
IBOutlet NSView *playlistView;
IBOutlet NSView *updatesView;
IBOutlet NSView *notificationsView;
__weak IBOutlet NSButton *iTunesStyleCheck;
@ -37,7 +36,6 @@
- (MIDIPane *)midiPane;
- (GeneralPane *)generalPane;
- (GeneralPreferencePane *)updatesPane;
- (GeneralPreferencePane *)playlistPane;
- (GeneralPreferencePane *)notificationsPane;
- (GeneralPreferencePane *)appearancePane;

View file

@ -43,7 +43,6 @@
topLevelObjects:nil];
return @[[plugin playlistPane],
[plugin hotKeyPane],
[plugin updatesPane],
[plugin outputPane],
[plugin generalPane],
[plugin notificationsPane],
@ -68,13 +67,6 @@
return generalPane;
}
- (GeneralPreferencePane *)updatesPane {
return [GeneralPreferencePane preferencePaneWithView:updatesView
title:NSLocalizedPrefString(@"Updates")
systemIconName:@"arrow.triangle.2.circlepath.circle.fill"
orOldIconNamed:@"updates"];
}
- (GeneralPreferencePane *)playlistPane {
return [GeneralPreferencePane preferencePaneWithView:playlistView
title:NSLocalizedPrefString(@"Playlist")

View file

@ -31,6 +31,17 @@ play with Cog. It is not necessary to add either your default Music folder,
your default Downloads folder, or your default Movies folder.
ADDENDUM - 2022-06-22
This branch is the App Store version. The only real difference between it and
the sparkle branch is that two commits which removed the Sparkle framework
were reverted in that branch. This branch contains an update to the README
and an extra empty commmit so that the version numbers sync up between the
two.
The App Store page for Cog is [here](https://apps.apple.com/us/app/cog-kode54/id1630499622), when it finally goes live.
ADDENDUM - 2013-09-30
I have forked this player to continue maintaining it for others to use, as its

View file

@ -1 +0,0 @@
Versions/Current/Autoupdate

View file

@ -1 +0,0 @@
Versions/Current/Headers

View file

@ -1 +0,0 @@
Versions/Current/Modules

View file

@ -1 +0,0 @@
Versions/Current/PrivateHeaders

View file

@ -1 +0,0 @@
Versions/Current/Resources

View file

@ -1 +0,0 @@
Versions/Current/Sparkle

View file

@ -1 +0,0 @@
Versions/Current/Updater.app

View file

@ -1,52 +0,0 @@
//
// SPUDownloadData.h
// Sparkle
//
// Created by Mayur Pawashe on 8/10/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
* A class for containing downloaded data along with some information about it.
*/
SU_EXPORT @interface SPUDownloadData : NSObject <NSSecureCoding>
/**
* The raw data that was downloaded.
*/
@property (nonatomic, readonly) NSData *data;
/**
* The URL that was fetched from.
*
* This may be different from the URL in the request if there were redirects involved.
*/
@property (nonatomic, readonly, copy) NSURL *URL;
/**
* The IANA charset encoding name if available. Eg: "utf-8"
*/
@property (nonatomic, readonly, nullable, copy) NSString *textEncodingName;
/**
* The MIME type if available. Eg: "text/plain"
*/
@property (nonatomic, readonly, nullable, copy) NSString *MIMEType;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,121 +0,0 @@
//
// SPUStandardUpdaterController.h
// Sparkle
//
// Created by Mayur Pawashe on 2/28/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SPUUpdater;
@class SPUStandardUserDriver;
@class NSMenuItem;
@protocol SPUUserDriver, SPUUpdaterDelegate, SPUStandardUserDriverDelegate;
/**
A controller class that instantiates a `SPUUpdater` and allows binding UI to its updater settings.
This class can be instantiated in a nib or created programmatically using `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:`.
The controller's updater targets the application's main bundle and uses Sparkle's standard user interface.
Typically, this class is used by sticking it as a custom NSObject subclass in an Interface Builder nib (probably in MainMenu) but it works well programmatically too.
The controller creates an `SPUUpdater` instance using a `SPUStandardUserDriver` and allows hooking up the check for updates action and handling menu item validation.
It also allows hooking up the updater's and user driver's delegates.
If you need more control over what bundle you want to update, or you want to provide a custom user interface (via `SPUUserDriver`), please use `SPUUpdater` directly instead.
*/
SU_EXPORT @interface SPUStandardUpdaterController : NSObject
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
/**
* Interface builder outlet for the updater's delegate.
*/
IBOutlet __weak id<SPUUpdaterDelegate> updaterDelegate;
/**
* Interface builder outlet for the user driver's delegate.
*/
IBOutlet __weak id<SPUStandardUserDriverDelegate> userDriverDelegate;
#pragma clang diagnostic pop
}
/**
Accessible property for the updater. Some properties on the updater can be binded via KVO
When instantiated from a nib, don't perform update checks before the application has finished launching in a MainMenu nib (i.e applicationDidFinishLaunching:) or before the corresponding window/view controller has been loaded (i.e, windowDidLoad or viewDidLoad). The updater is not guaranteed to be started yet before these points.
*/
@property (nonatomic, readonly) SPUUpdater *updater;
/**
Accessible property for the updater's user driver.
*/
@property (nonatomic, readonly) SPUStandardUserDriver *userDriver;
/**
Create a new `SPUStandardUpdaterController` from a nib.
You cannot call this initializer directly. You must instantiate a `SPUStandardUpdaterController` inside of a nib (typically the MainMenu nib) to use it.
To create a `SPUStandardUpdaterController` programmatically, use `-initWithUpdaterDelegate:userDriverDelegate:` or `-initWithStartingUpdater:updaterDelegate:userDriverDelegate:` instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
Create a new `SPUStandardUpdaterController` programmatically.
The updater is started automatically. See `-startUpdater` for more information.
*/
- (instancetype)initWithUpdaterDelegate:(nullable id<SPUUpdaterDelegate>)updaterDelegate userDriverDelegate:(nullable id<SPUStandardUserDriverDelegate>)userDriverDelegate;
/**
Create a new `SPUStandardUpdaterController` programmatically allowing you to specify whether or not to start the updater immediately.
You can specify whether or not you want to start the updater immediately.
If you do not start the updater, you must invoke `-startUpdater` at a later time to start it.
*/
- (instancetype)initWithStartingUpdater:(BOOL)startUpdater updaterDelegate:(nullable id<SPUUpdaterDelegate>)updaterDelegate userDriverDelegate:(nullable id<SPUStandardUserDriverDelegate>)userDriverDelegate;
/**
Starts the updater if it has not already been started.
You should only call this method yourself if you opted out of starting the updater on initialization.
Hence, do not call this yourself if you are instantiating this controller from a nib.
This invokes `-[SPUUpdater startUpdater:]`. If the application is misconfigured with Sparkle, an error is logged and an alert is shown to the user (after a few seconds) to contact the developer.
If you want more control over this behavior, you can create your own `SPUUpdater` instead of using `SPUStandardUpdaterController`.
*/
- (void)startUpdater;
/**
Explicitly checks for updates and displays a progress dialog while doing so.
This method is meant for a main menu item.
Connect any NSMenuItem to this action in Interface Builder or programmatically,
and Sparkle will check for updates and report back its findings verbosely when it is invoked.
When the target/action of the menu item is set to this controller and this method,
this controller also handles enabling/disabling the menu item by checking
`-[SPUUpdater canCheckForUpdates]`
This action checks updates by invoking `-[SPUUpdater checkForUpdates]`
*/
- (IBAction)checkForUpdates:(nullable id)sender;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,47 +0,0 @@
//
// SPUStandardUserDriver.h
// Sparkle
//
// Created by Mayur Pawashe on 2/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SPUUserDriver.h"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SPUUserDriver.h>
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@protocol SPUStandardUserDriverDelegate;
/**
Sparkle's standard built-in user driver for updater interactions
*/
SU_EXPORT @interface SPUStandardUserDriver : NSObject <SPUUserDriver>
/**
Initializes a Sparkle's standard user driver for user update interactions
@param hostBundle The target bundle of the host that is being updated.
@param delegate The optional delegate to this user driver.
*/
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle delegate:(nullable id<SPUStandardUserDriverDelegate>)delegate;
/**
Use initWithHostBundle:delegate: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,193 +0,0 @@
//
// SPUStandardUserDriverDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 3/3/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@protocol SUVersionDisplay;
@class SUAppcastItem;
@class SPUUserUpdateState;
/**
A protocol for Sparkle's standard user driver's delegate
This includes methods related to UI interactions
*/
SU_EXPORT @protocol SPUStandardUserDriverDelegate <NSObject>
@optional
/**
Called before showing a modal alert window,
to give the opportunity to hide attached windows that may get in the way.
*/
- (void)standardUserDriverWillShowModalAlert;
/**
Called after showing a modal alert window,
to give the opportunity to hide attached windows that may get in the way.
*/
- (void)standardUserDriverDidShowModalAlert;
/**
Returns an object that formats version numbers for display to the user.
If you don't implement this method or return @c nil, the standard version formatter will be used.
*/
- (_Nullable id <SUVersionDisplay>)standardUserDriverRequestsVersionDisplayer;
/**
Decides whether or not the standard user driver should provide an option to show full release notes to the user.
When a user checks for new updates and no new update is found, Sparkle by default will offer to show the application's version history to the user
by providing a "Version History" button in the no new update available alert.
If this delegate method is implemented to return `NO`, then Sparkle will not provide an option to show full release notes to the user.
@param item The appcast item corresponding to the latest version available.
@return @c YES to allow Sparkle to show full release notes to the user, otherwise @c NO to disallow this.
*/
- (BOOL)standardUserDriverShouldShowVersionHistoryForAppcastItem:(SUAppcastItem *)item;
/**
Handles showing the full release notes to the user.
When a user checks for new updates and no new update is found, Sparkle will offer to show the application's version history to the user
by providing a "Version History" button in the no new update available alert.
If this delegate method is not implemented, Sparkle will instead offer to open the
`fullReleaseNotesLink` (or `releaseNotesLink` if the former is unavailable) from the appcast's latest `item` in the user's web browser.
If this delegate method is implemented, Sparkle will instead ask the delegate to show the full release notes to the user.
A delegate may want to implement this method if they want to show in-app or offline release notes.
@param item The appcast item corresponding to the latest version available.
*/
- (void)standardUserDriverShowVersionHistoryForAppcastItem:(SUAppcastItem *)item;
/**
Specifies whether or not the download, extraction, and installing status windows allows to be minimized.
By default, the status window showing the current status of the update (download, extraction, ready to install) is allowed to be minimized
for regular application bundle updates.
@return @c YES if the status window is allowed to be minimized (default behavior), otherwise @c NO.
*/
- (BOOL)standardUserDriverAllowsMinimizableStatusWindow;
/**
Declares whether or not gentle scheduled update reminders are supported.
The delegate may implement scheduled update reminders that are presented in a gentle manner by implementing one or both of:
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:` and `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:`
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@return @c YES if gentle scheduled update reminders are implemented by standard user driver delegate, otherwise @c NO (default).
*/
@property (nonatomic, readonly) BOOL supportsGentleScheduledUpdateReminders;
/**
Specifies if the standard user driver should handle showing a new scheduled update, or if its delegate should handle showing the update instead.
If you implement this method and return @c NO the delegate is then responsible for showing the update,
which must be implemented and done in `-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
The motivation for the delegate being responsible for showing updates is to override Sparkle's default behavior
and add gentle reminders for new updates.
Returning @c YES is the default behavior and allows the standard user driver to handle showing the update.
If the standard user driver handles showing the update, `immediateFocus` reflects whether or not it will show the update in immediate and utmost focus.
The standard user driver may choose to show the update in immediate and utmost focus when the app was launched recently
or the system has been idle for some time.
If `immediateFocus` is @c NO the standard user driver may want to defer showing the update until the user comes back to the app.
For background running applications, when `immediateFocus` is @c NO the standard user driver will always want to show
the update alert immediately, but behind other running applications or behind the app's own windows if it's currently active.
There should be no side effects made when implementing this method so you should just return @c YES or @c NO
You will also want to implement `-standardUserDriverWillHandleShowingUpdate:forUpdate:state:` for adding additional update reminders.
This method is not called for user-initiated update checks. The standard user driver always handles those.
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@param update The update the standard user driver should show.
@param immediateFocus If @c immediateFocus is @c YES, then the standard user driver proposes to show the update in immediate and utmost focus. See discussion for more details.
@return @c YES if the standard user should handle showing the scheduled update (default behavior), otherwise @c NO if the delegate handles showing it.
*/
- (BOOL)standardUserDriverShouldHandleShowingScheduledUpdate:(SUAppcastItem *)update andInImmediateFocus:(BOOL)immediateFocus;
/**
Called before an update will be shown to the user.
If the standard user driver handles showing the update, `handleShowingUpdate` will be `YES`.
Please see `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:` for how the standard user driver
may handle showing scheduled updates when `handleShowingUpdate` is `YES` and `state.userInitiated` is `NO`.
If the delegate declared it handles showing the update by returning @c NO in `-standardUserDriverShouldHandleShowingScheduledUpdate:andInImmediateFocus:`
then the delegate should handle showing update reminders in this method, or at some later point.
In this case, `handleShowingUpdate` will be @c NO.
To bring the update alert in focus, you may call `-[SPUStandardUpdaterController checkForUpdates:]` or `-[SPUUpdater checkForUpdates]`.
You may want to show additional UI indicators in your application that will show this update in focus
and want to dismiss additional UI indicators in `-standardUserDriverWillFinishUpdateSession` or `-standardUserDriverDidReceiveUserAttentionForUpdate:`
If `state.userInitiated` is @c YES then the standard user driver always handles showing the new update and `handleShowingUpdate` will be @c YES.
In this case, it may still be useful for the delegate to intercept this method right before a new update will be shown.
This method is not called when bringing an update that has already been presented back in focus.
Visit https://sparkle-project.org/documentation/gentle-reminders for more information and examples.
@param handleShowingUpdate @c YES if the standard user driver handles showing the update, otherwise @c NO if the delegate handles showing the update.
@param update The update that will be shown.
@param state The user state of the update which includes if the update check was initiated by the user.
*/
- (void)standardUserDriverWillHandleShowingUpdate:(BOOL)handleShowingUpdate forUpdate:(SUAppcastItem *)update state:(SPUUserUpdateState *)state;
/**
Called when a new update first receives attention from the user.
This occurs either when the user first brings the update alert in utmost focus or when the user makes a choice to install an update or dismiss/skip it.
This may be useful to intercept for dismissing custom attention-based UI indicators (e.g, user notifications) introduced when implementing
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
For custom UI indicators that need to still be on screen after the user has started to install an update, please see `-standardUserDriverWillFinishUpdateSession`.
@param update The new update that the user gave attention to.
*/
- (void)standardUserDriverDidReceiveUserAttentionForUpdate:(SUAppcastItem *)update;
/**
Called before the standard user driver session will finish its current update session.
This may occur after the user has dismissed / skipped a new update or after an update error has occurred.
For updaters updating external/other bundles, this may also be called after an update has been successfully installed.
This may be useful to intercept for dismissing custom UI indicators introduced when implementing
`-standardUserDriverWillHandleShowingUpdate:forUpdate:state:`
For UI indicators that need to be dismissed when the user has given attention to a new update alert,
please see `-standardUserDriverDidReceiveUserAttentionForUpdate:`
*/
- (void)standardUserDriverWillFinishUpdateSession;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,33 +0,0 @@
//
// SPUUpdateCheck.h
// SPUUpdateCheck
//
// Created by Mayur Pawashe on 8/28/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SPUUpdateCheck_h
#define SPUUpdateCheck_h
/**
Describes the type of update check being performed.
Each update check corresponds to an update check method on `SPUUpdater`.
*/
typedef NS_ENUM(NSInteger, SPUUpdateCheck)
{
/**
The user-initiated update check corresponding to `-[SPUUpdater checkForUpdates]`.
*/
SPUUpdateCheckUpdates = 0,
/**
The background scheduled update check corresponding to `-[SPUUpdater checkForUpdatesInBackground]`.
*/
SPUUpdateCheckUpdatesInBackground = 1,
/**
The informational probe update check corresponding to `-[SPUUpdater checkForUpdateInformation]`.
*/
SPUUpdateCheckUpdateInformation = 2
};
#endif /* SPUUpdateCheck_h */

View file

@ -1,42 +0,0 @@
//
// SPUUpdatePermissionRequest.h
// Sparkle
//
// Created by Mayur Pawashe on 8/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
This class represents information needed to make a permission request for checking updates.
*/
SU_EXPORT @interface SPUUpdatePermissionRequest : NSObject<NSSecureCoding>
/**
Initializes a new update permission request instance.
@param systemProfile The system profile information.
*/
- (instancetype)initWithSystemProfile:(NSArray<NSDictionary<NSString *, NSString *> *> *)systemProfile;
/**
A read-only property for the user's system profile.
*/
@property (nonatomic, readonly) NSArray<NSDictionary<NSString *, NSString *> *> *systemProfile;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,368 +0,0 @@
//
// SPUUpdater.h
// Sparkle
//
// Created by Andy Matuschak on 1/4/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SPUUserDriver.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#import <Sparkle/SPUUserDriver.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SUAppcastItem, SUAppcast;
@protocol SPUUpdaterDelegate;
/**
The main API in Sparkle for controlling the update mechanism.
This class is used to configure the update parameters as well as manually and automatically schedule and control checks for updates.
For convenience, you can create a standard or nib instantiable updater by using `SPUStandardUpdaterController`.
Prefer to set initial properties in your bundle's Info.plist as described in [Customizing Sparkle](https://sparkle-project.org/documentation/customization/).
Otherwise only if you need dynamic behavior for user settings should you set properties on the updater such as:
- `automaticallyChecksForUpdates`
- `updateCheckInterval`
- `automaticallyDownloadsUpdates`
- `feedURL`
Please view the documentation on each of these properties for more detail if you are to configure them dynamically.
*/
SU_EXPORT @interface SPUUpdater : NSObject
/**
Initializes a new `SPUUpdater` instance
This creates an updater, but to start it and schedule update checks `-startUpdater:` needs to be invoked first.
Related: See `SPUStandardUpdaterController` which wraps a `SPUUpdater` instance and is suitable for instantiating inside of nib files.
@param hostBundle The bundle that should be targeted for updating.
@param applicationBundle The application bundle that should be waited for termination and relaunched (unless overridden). Usually this can be the same as hostBundle. This may differ when updating a plug-in or other non-application bundle.
@param userDriver The user driver that Sparkle uses for user update interaction.
@param delegate The delegate for `SPUUpdater`.
*/
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle applicationBundle:(NSBundle *)applicationBundle userDriver:(id <SPUUserDriver>)userDriver delegate:(nullable id<SPUUpdaterDelegate>)delegate;
/**
Use `-initWithHostBundle:applicationBundle:userDriver:delegate:` or `SPUStandardUpdaterController` standard adapter instead.
If you want to drop an updater into a nib, use `SPUStandardUpdaterController`.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
Starts the updater.
This method first checks if Sparkle is configured properly. A valid feed URL should be set before this method is invoked.
If the configuration is valid, an update cycle is started in the next main runloop cycle.
During this cycle, a permission prompt may be brought up (if needed) for checking if the user wants automatic update checking.
Otherwise if automatic update checks are enabled, a scheduled update alert may be brought up if enough time has elapsed since the last check.
See `automaticallyChecksForUpdates` for more information.
After starting the updater and before the next runloop cycle, one of `-checkForUpdates`, `-checkForUpdatesInBackground`, or `-checkForUpdateInformation` can be invoked.
This may be useful if you want to check for updates immediately or without showing a potential permission prompt.
If the updater cannot be started (i.e, due to a configuration issue in the application), you may want to fall back appropriately.
For example, the standard updater controller (`SPUStandardUpdaterController`) alerts the user that the app is misconfigured and to contact the developer.
This must be called on the main thread.
@param error The error that is populated if this method fails. Pass NULL if not interested in the error information.
@return YES if the updater started otherwise NO with a populated error
*/
- (BOOL)startUpdater:(NSError * __autoreleasing *)error;
/**
Checks for updates, and displays progress while doing so if needed.
This is meant for users initiating a new update check or checking the current update progress.
If an update hasn't started, the user may be shown that a new check for updates is occurring.
If an update has already been downloaded or begun installing from a previous session, the user may be presented to install that update.
If the user is already being presented with an update, that update will be shown to the user in active focus.
This will find updates that the user has previously opted into skipping.
See `canCheckForUpdates` property which can determine when this method may be invoked.
*/
- (void)checkForUpdates;
/**
Checks for updates, but does not show any UI unless an update is found.
You usually do not need to call this method directly. If `automaticallyChecksForUpdates` is @c YES,
Sparkle calls this method automatically according to its update schedule using the `updateCheckInterval`
and the `lastUpdateCheckDate`. Therefore, you should typically only consider calling this method directly if you
opt out of automatic update checks. Calling this method when updating your own bundle is invalid if Sparkle is configured
to ask the user's permission to check for updates automatically and `automaticallyChecksForUpdates` is `NO`.
If you want to reset the updater's cycle after an updater setting change, see `resetUpdateCycle` or `resetUpdateCycleAfterShortDelay` instead.
This is meant for programmatically initiating a check for updates in the background without the user initiating it.
This check will not show UI if no new updates are found.
If a new update is found, the updater's user driver may handle showing it at an appropriate (but not necessarily immediate) time.
If you want control over when and how a new update is shown, please see https://sparkle-project.org/documentation/gentle-reminders/
Note if automated downloading/installing is turned on, either a new update may be downloaded in the background to be installed silently,
or an already downloaded update may be shown.
This will not find updates that the user has opted into skipping.
This method does not do anything if there is a `sessionInProgress`.
*/
- (void)checkForUpdatesInBackground;
/**
Begins a "probing" check for updates which will not actually offer to
update to that version.
However, the delegate methods
`-[SPUUpdaterDelegate updater:didFindValidUpdate:]` and
`-[SPUUpdaterDelegate updaterDidNotFindUpdate:]` will be called,
so you can use that information in your UI.
`-[SPUUpdaterDelegate updater:didFinishUpdateCycleForUpdateCheck:error:]` will be called when
this probing check is completed.
Updates that have been skipped by the user will not be found.
This method does not do anything if there is a `sessionInProgress`.
*/
- (void)checkForUpdateInformation;
/**
A property indicating whether or not updates can be checked by the user.
An update check can be made by the user when an update session isn't in progress, or when an update or its progress is being shown to the user.
A user cannot check for updates when data (such as the feed or an update) is still being downloaded automatically in the background.
This property is suitable to use for menu item validation for seeing if `-checkForUpdates` can be invoked.
This property is also KVO-compliant.
Note this property does not reflect whether or not an update session is in progress. Please see `sessionInProgress` property instead.
*/
@property (nonatomic, readonly) BOOL canCheckForUpdates;
/**
A property indicating whether or not an update session is in progress.
An update session is in progress when the appcast is being downloaded, an update is being downloaded,
an update is being shown, update permission is being requested, or the installer is being started.
An active session is when Sparkle's fired scheduler is running.
Note an update session may not be running even though Sparkle's installer (ran as a separate process) may be running,
or even though the update has been downloaded but the installation has been deferred. In both of these cases, a new update session
may be activated with the update resumed at a later point (automatically or manually).
See also:
- `canCheckForUpdates` property which is more suited for menu item validation and deciding if the user can initiate update checks.
- `-[SPUUpdaterDelegate updater:didFinishUpdateCycleForUpdateCheck:error:]` which lets the updater delegate know when an update cycle and session finishes.
*/
@property (nonatomic, readonly) BOOL sessionInProgress;
/**
A property indicating whether or not to check for updates automatically.
By default, Sparkle asks users on second launch for permission if they want automatic update checks enabled
and sets this property based on their response. If `SUEnableAutomaticChecks` is set in the Info.plist,
this permission request is not performed however.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
For testing environments, you can disable update checks by passing `-SUEnableAutomaticChecks NO`
to your app's command line arguments instead of setting this property.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) BOOL automaticallyChecksForUpdates;
/**
A property indicating the current automatic update check interval in seconds.
Prefer to set SUScheduledCheckInterval directly in your Info.plist for setting the initial value.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) NSTimeInterval updateCheckInterval;
/**
A property indicating whether or not updates can be automatically downloaded in the background.
By default, updates are not automatically downloaded.
By default starting from Sparkle 2.4, users are provided an option to opt in to automatically downloading and installing updates when they are asked if they want automatic update checks enabled.
The default value for this option is based on what the developer sets `SUAutomaticallyUpdate` in their Info.plist.
This is not done if `SUEnableAutomaticChecks` is set in the Info.plist however. Please check `automaticallyChecksForUpdates` property for more details.
Note that the developer can disallow automatic downloading of updates from being enabled (via `SUAllowsAutomaticUpdates` Info.plist key).
In this case, this property will return NO regardless of how this property is set.
Prefer to set `SUAutomaticallyUpdate` directly in your Info.plist for setting the initial value.
Setting this property will persist in the host bundle's user defaults.
Hence developers shouldn't maintain an additional user default for this property.
Only set this property if the user wants to change the default via a user settings option.
Do not always set it on launch unless you want to ignore the user's preference.
*/
@property (nonatomic) BOOL automaticallyDownloadsUpdates;
/**
The URL of the appcast used to download update information.
If the updater's delegate implements `-[SPUUpdaterDelegate feedURLStringForUpdater:]`, this will return that feed URL.
Otherwise if the feed URL has been set before using `-[SPUUpdater setFeedURL:]`, the feed URL returned will be retrieved from the host bundle's user defaults.
Otherwise the feed URL in the host bundle's Info.plist will be returned.
If no feed URL can be retrieved, returns nil.
For setting a primary feed URL, please set the `SUFeedURL` property in your Info.plist.
For setting an alternative feed URL, please prefer `-[SPUUpdaterDelegate feedURLStringForUpdater:]` over `-setFeedURL:`.
Please see the documentation for `-setFeedURL:` for migrating away from that API.
This property must be called on the main thread; calls from background threads will return nil.
*/
@property (nonatomic, readonly, nullable) NSURL *feedURL;
/**
Set the URL of the appcast used to download update information. This method is deprecated.
Setting this property will persist in the host bundle's user defaults.
To avoid this undesirable behavior, please consider implementing
`-[SPUUpdaterDelegate feedURLStringForUpdater:]` instead of using this method.
Calling `-clearFeedURLFromUserDefaults` will remove any feed URL that has been set in the host bundle's user defaults.
Passing nil to this method can also do this, but using `-clearFeedURLFromUserDefaults` is preferred.
To migrate away from using this API, you must clear and remove any feed URLs set in the user defaults through this API.
If you do not need to alternate between multiple feeds, set the SUFeedURL in your Info.plist instead of invoking this method.
For beta updates, you may consider migrating to `-[SPUUpdaterDelegate allowedChannelsForUpdater:]` in the future.
Updaters that update other developer's bundles should not call this method.
This method must be called on the main thread; calls from background threads will have no effect.
*/
- (void)setFeedURL:(nullable NSURL *)feedURL __deprecated_msg("Please call -[SPUUpdater clearFeedURLFromUserDefaults] to migrate away from using this API and transition to either specifying the feed URL in your Info.plist, using channels in Sparkle 2, or using -[SPUUpdaterDelegate feedURLStringForUpdater:] to specify the dynamic feed URL at runtime");
/**
Clears any feed URL from the host bundle's user defaults that was set via `-setFeedURL:`
You should call this method if you have used `-setFeedURL:` in the past and want to stop using that API.
Otherwise for compatibility Sparkle will prefer to use the feed URL that was set in the user defaults over the one that was specified in the host bundle's Info.plist,
which is often undesirable (except for testing purposes).
If a feed URL is found stored in the host bundle's user defaults (from calling `-setFeedURL:`) before it gets cleared,
then that previously set URL is returned from this method.
This method should be called as soon as possible, after your application finished launching or right after the updater has been started
if you manually manage starting the updater.
Updaters that update other developer's bundles should not call this method.
This method must be called on the main thread.
@return A previously set feed URL in the host bundle's user defaults, if available, otherwise this returns `nil`
*/
- (nullable NSURL *)clearFeedURLFromUserDefaults;
/**
The host bundle that is being updated.
*/
@property (nonatomic, readonly) NSBundle *hostBundle;
/**
The user agent used when checking for updates.
By default the user agent string returned is in the format:
`$(BundleDisplayName)/$(BundleDisplayVersion) Sparkle/$(SparkleDisplayVersion)`
BundleDisplayVersion is derived from the main application's Info.plist's CFBundleShortVersionString.
Note if Sparkle is being used to update another application, the bundle information retrieved is from the main application performing the updating.
This default implementation can be overridden.
*/
@property (nonatomic, copy) NSString *userAgentString;
/**
The HTTP headers used when checking for updates, downloading release notes, and downloading updates.
The keys of this dictionary are HTTP header fields and values are corresponding values.
*/
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSString *> *httpHeaders;
/**
A property indicating whether or not the user's system profile information is sent when checking for updates.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL sendsSystemProfile;
/**
The date of the last update check or nil if no check has been performed yet.
For testing purposes, the last update check is stored in the `SULastCheckTime` key in the host bundle's user defaults.
For example, `defaults delete my-bundle-id SULastCheckTime` can be invoked to clear the last update check time and test
if update checks are automatically scheduled.
*/
@property (nonatomic, readonly, copy, nullable) NSDate *lastUpdateCheckDate;
/**
Appropriately re-schedules the update checking timer according to the current updater settings.
This method should only be called in response to a user changing updater settings. This method may trigger a new update check to occur in the background if an updater setting such as the updater's feed or allowed channels has changed.
If the `updateCheckInterval` or `automaticallyChecksForUpdates` properties are changed, this method is automatically invoked after a short delay using `-resetUpdateCycleAfterShortDelay`. In these cases, manually resetting the update cycle is not necessary.
See also `-resetUpdateCycleAfterShortDelay` which gives the user a short delay before triggering a cycle reset.
*/
- (void)resetUpdateCycle;
/**
Appropriately re-schedules the update checking timer according to the current updater settings after a short cancellable delay.
This method calls `resetUpdateCycle` after a short delay to give the user a short amount of time to cancel changing an updater setting.
If this method is called again, any previous reset request that is still inflight will be cancelled.
For example, if the user changes the `automaticallyChecksForUpdates` setting to `YES`, but quickly undoes their change then
no cycle reset will be done.
If the `updateCheckInterval` or `automaticallyChecksForUpdates` properties are changed, this method is automatically invoked. In these cases, manually resetting the update cycle is not necessary.
*/
- (void)resetUpdateCycleAfterShortDelay;
/**
The system profile information that is sent when checking for updates.
*/
@property (nonatomic, readonly, copy) NSArray<NSDictionary<NSString *, NSString *> *> *systemProfileArray;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,480 +0,0 @@
//
// SPUUpdaterDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 8/12/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SPUUpdateCheck.h"
#import "SPUUserUpdateState.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#import <Sparkle/SPUUpdateCheck.h>
#import <Sparkle/SPUUserUpdateState.h>
#endif
@protocol SUVersionComparison;
@class SPUUpdater, SUAppcast, SUAppcastItem, SPUUserUpdateState;
NS_ASSUME_NONNULL_BEGIN
// -----------------------------------------------------------------------------
// SUUpdater Notifications for events that might be interesting to more than just the delegate
// The updater will be the notification object
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
// -----------------------------------------------------------------------------
// System Profile Keys
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUSystemProfilerApplicationNameKey;
SU_EXPORT extern NSString *const SUSystemProfilerApplicationVersionKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPU64bitKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUCountKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUFrequencyKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUTypeKey;
SU_EXPORT extern NSString *const SUSystemProfilerCPUSubtypeKey;
SU_EXPORT extern NSString *const SUSystemProfilerHardwareModelKey;
SU_EXPORT extern NSString *const SUSystemProfilerMemoryKey;
SU_EXPORT extern NSString *const SUSystemProfilerOperatingSystemVersionKey;
SU_EXPORT extern NSString *const SUSystemProfilerPreferredLanguageKey;
// -----------------------------------------------------------------------------
// SPUUpdater Delegate:
// -----------------------------------------------------------------------------
/**
Provides delegation methods to control the behavior of an `SPUUpdater` object.
*/
@protocol SPUUpdaterDelegate <NSObject>
@optional
/**
Returns whether to allow Sparkle to check for updates.
For example, this may be used to prevent Sparkle from interrupting a setup assistant.
Alternatively, you may want to consider starting the updater after eg: the setup assistant finishes.
Note in Swift, this method returns Void and is marked with the throws keyword. If this method
doesn't throw an error, the updater may perform an update check. Otherwise if an error is thrown (we recommend using an NSError),
then the updater may not perform an update check.
@param updater The updater instance.
@param updateCheck The type of update check that will be performed if the updater is allowed to check for updates.
@param error The populated error object if the updater may not perform a new update check. The @c NSLocalizedDescriptionKey user info key should be populated indicating a description of the error.
@return @c YES if the updater is allowed to check for updates, otherwise @c NO
*/
- (BOOL)updater:(SPUUpdater *)updater mayPerformUpdateCheck:(SPUUpdateCheck)updateCheck error:(NSError * __autoreleasing *)error;
/**
Returns the set of Sparkle channels the updater is allowed to find new updates from.
An appcast item can specify a channel the update is posted to. Without specifying a channel, the appcast item is posted to the default channel.
For instance:
```
<item>
<sparkle:version>2.0 Beta 1</sparkle:version>
<sparkle:channel>beta</sparkle:channel>
</item>
```
This example posts an update to the @c beta channel, so only updaters that are allowed to use the @c beta channel can find this update.
If the @c <sparkle:channel> element is not present, the update item is posted to the default channel and can be found by any updater.
You can pick any name you'd like for the channel. The valid characters for channel names are letters, numbers, dashes, underscores, and periods.
Note to use this feature, all app versions that your users may update from in your feed must use a version of Sparkle that supports this feature.
This feature was added in Sparkle 2.
@return The set of channel names the updater is allowed to find new updates in. An empty set is the default behavior,
which means the updater will only look for updates in the default channel. The default channel is always included in the allowed set.
*/
- (NSSet<NSString *> *)allowedChannelsForUpdater:(SPUUpdater *)updater;
/**
Returns a custom appcast URL used for checking for new updates.
Override this to dynamically specify the feed URL.
@param updater The updater instance.
@return An appcast feed URL to check for new updates in, or @c nil for the default behavior and if you don't want to be delegated this task.
*/
- (nullable NSString *)feedURLStringForUpdater:(SPUUpdater *)updater;
/**
Returns additional parameters to append to the appcast URL's query string.
This is potentially based on whether or not Sparkle will also be sending along the system profile.
@param updater The updater instance.
@param sendingProfile Whether the system profile will also be sent.
@return An array of dictionaries with keys: `key`, `value`, `displayKey`, `displayValue`, the latter two being specifically for display to the user.
*/
- (NSArray<NSDictionary<NSString *, NSString *> *> *)feedParametersForUpdater:(SPUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;
/**
Returns whether Sparkle should prompt the user about checking for new updates automatically.
Use this to override the default behavior, which is to prompt for permission to check for updates on second app launch
(if SUEnableAutomaticChecks is not specified).
This method is not called if SUEnableAutomaticChecks is defined in Info.plist or
if the user has responded to a permission prompt before.
@param updater The updater instance.
@return @c YES if the updater should prompt for permission to check for new updates automatically, otherwise @c NO
*/
- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SPUUpdater *)updater;
/**
Returns an allowed list of system profile keys to be appended to the appcast URL's query string.
By default all keys will be included. This method allows overriding which keys should only be allowed.
@param updater The updater instance.
@return An array of system profile keys to include in the appcast URL's query string. Elements must be one of the `SUSystemProfiler*Key` constants. Return @c nil for the default behavior and if you don't want to be delegated this task.
*/
- (nullable NSArray<NSString *> *)allowedSystemProfileKeysForUpdater:(SPUUpdater *)updater;
/**
Called after Sparkle has downloaded the appcast from the remote server.
Implement this if you want to do some special handling with the appcast once it finishes loading.
@param updater The updater instance.
@param appcast The appcast that was downloaded from the remote server.
*/
- (void)updater:(SPUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
/**
Called when a new valid update is found by the update driver.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SPUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item;
/**
Called when a valid new update is not found.
There are various reasons a new update is unavailable and can't be installed.
The userInfo dictionary on the error is populated with three keys:
- `SPULatestAppcastItemFoundKey`: if available, this may provide the latest `SUAppcastItem` that was found. This will be @c nil if it's unavailable.
- `SPUNoUpdateFoundReasonKey`: This will provide the `SPUNoUpdateFoundReason`.
For example the reason could be because the latest version in the feed requires a newer OS version or could be because the user is already on the latest version.
- `SPUNoUpdateFoundUserInitiatedKey`: A boolean that indicates if a new update was not found when the user intitiated an update check manually.
@param updater The updater instance.
@param error An error containing information on why a new valid update was not found
*/
- (void)updaterDidNotFindUpdate:(SPUUpdater *)updater error:(NSError *)error;
/**
Called when a valid new update is not found.
If more information is needed on why an update was not found, use `-[SPUUpdaterDelegate updaterDidNotFindUpdate:error:]` instead.
@param updater The updater instance.
*/
- (void)updaterDidNotFindUpdate:(SPUUpdater *)updater;
/**
Returns the item in the appcast corresponding to the update that should be installed.
Please consider using or migrating to other supported features before adopting this method.
Specifically:
- If you want to filter out certain tagged updates (like beta updates), consider `-[SPUUpdaterDelegate allowedChannelsForUpdater:]` instead.
- If you want to treat certain updates as informational-only, consider supplying @c <sparkle:informationalUpdate> with a set of affected versions users are updating from.
If you're using special logic or extensions in your appcast, implement this to use your own logic for finding a valid update, if any, in the given appcast.
Do not base your logic by filtering out items with a minimum or maximum OS version or minimum autoupdate version
because Sparkle already has logic for determining whether or not those items should be filtered out.
Also do not return a non-top level item from the appcast such as a delta item. Delta items will be ignored.
Sparkle picks the delta item from your selection if the appropriate one is available.
This method will not be invoked with an appcast that has zero items. Pick the best item from the appcast.
If an item is available that has the same version as the application or bundle to update, do not pick an item that is worse than that version.
This method may be called multiple times for different selections and filters. This method should be efficient.
Return `+[SUAppcastItem emptyAppcastItem]` if no appcast item is valid.
Return @c nil if you don't want to be delegated this task and want to let Sparkle handle picking the best valid update.
@param appcast The appcast that was downloaded from the remote server.
@param updater The updater instance.
@return The best valid appcast item.
*/
- (nullable SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SPUUpdater *)updater;
/**
Returns whether or not the updater should proceed with the new chosen update from the appcast.
By default, the updater will always proceed with the best selected update found in an appcast. Override this to override this behavior.
If you return @c NO and populate the @c error, the user is not shown this @c updateItem nor is the update downloaded or installed.
Note in Swift, this method returns Void and is marked with the throws keyword. If this method doesn't throw an error, the updater will proceed with the update.
Otherwise if an error is thrown (we recommend using an NSError), then the will not proceed with the update.
@param updater The updater instance.
@param updateItem The selected update item to proceed with.
@param updateCheck The type of update check that would be performed if proceeded.
@param error An error object that must be populated by the delegate if the updater should not proceed with the update. The @c NSLocalizedDescriptionKey user info key should be populated indicating a description of the error.
@return @c YES if the updater should proceed with @c updateItem, otherwise @c NO if the updater should not proceed with the update with an @c error populated.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldProceedWithUpdate:(SUAppcastItem *)updateItem updateCheck:(SPUUpdateCheck)updateCheck error:(NSError * __autoreleasing *)error;
/**
Called when a user makes a choice to install, dismiss, or skip an update.
If the @c choice is `SPUUserUpdateChoiceDismiss` and @c state.stage is `SPUUserUpdateStageDownloaded` the downloaded update is kept
around until the next time Sparkle reminds the user of the update.
If the @c choice is `SPUUserUpdateChoiceDismiss` and @c state.stage is `SPUUserUpdateStageInstalling` the update is still set to install on application termination.
If the @c choice is `SPUUserUpdateChoiceSkip` the user will not be reminded in the future for this update unless they initiate an update check themselves.
If @c updateItem.isInformationOnlyUpdate is @c YES the @c choice cannot be `SPUUserUpdateChoiceInstall`.
@param updater The updater instance.
@param choice The choice (install, dismiss, or skip) the user made for this @c updateItem
@param updateItem The appcast item corresponding to the update that the user made a choice on.
@param state The current state for the update which includes if the update has already been downloaded or already installing.
*/
- (void)updater:(SPUUpdater *)updater userDidMakeChoice:(SPUUserUpdateChoice)choice forUpdate:(SUAppcastItem *)updateItem state:(SPUUserUpdateState *)state;
/**
Returns whether the release notes (if available) should be downloaded after an update is found and shown.
This is specifically for the @c <releaseNotesLink> element in the appcast item.
@param updater The updater instance.
@param updateItem The update item to download and show release notes from.
@return @c YES to download and show the release notes if available, otherwise @c NO. The default behavior is @c YES.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldDownloadReleaseNotesForUpdate:(SUAppcastItem *)updateItem;
/**
Called immediately before downloading the specified update.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be downloaded.
@param request The mutable URL request that will be used to download the update.
*/
- (void)updater:(SPUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request;
/**
Called immediately after successful download of the specified update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that has been downloaded.
*/
- (void)updater:(SPUUpdater *)updater didDownloadUpdate:(SUAppcastItem *)item;
/**
Called after the specified update failed to download.
@param updater The updater instance.
@param item The appcast item corresponding to the update that failed to download.
@param error The error generated by the failed download.
*/
- (void)updater:(SPUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error;
/**
Called when the user cancels an update while it is being downloaded.
@param updater The updater instance.
*/
- (void)userDidCancelDownload:(SPUUpdater *)updater;
/**
Called immediately before extracting the specified downloaded update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that is proposed to be extracted.
*/
- (void)updater:(SPUUpdater *)updater willExtractUpdate:(SUAppcastItem *)item;
/**
Called immediately after extracting the specified downloaded update.
@param updater The SUUpdater instance.
@param item The appcast item corresponding to the update that has been extracted.
*/
- (void)updater:(SPUUpdater *)updater didExtractUpdate:(SUAppcastItem *)item;
/**
Called immediately before installing the specified update.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SPUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item;
/**
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This may also not be called if the application is not going to relaunch after it terminates.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
@param installHandler The install handler that must be completed before continuing with the relaunch.
@return @c YES to delay the relaunch until @c installHandler is invoked.
*/
- (BOOL)updater:(SPUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvokingBlock:(void (^)(void))installHandler;
/**
Returns whether the application should be relaunched at all.
Some apps **cannot** be relaunched under certain circumstances.
This method can be used to explicitly prevent a relaunch.
@param updater The updater instance.
@return @c YES if the updater should be relaunched, otherwise @c NO if it shouldn't.
*/
- (BOOL)updaterShouldRelaunchApplication:(SPUUpdater *)updater;
/**
Called immediately before relaunching.
@param updater The updater instance.
*/
- (void)updaterWillRelaunchApplication:(SPUUpdater *)updater;
/**
Returns an object that compares version numbers to determine their arithmetic relation to each other.
This method allows you to provide a custom version comparator.
If you don't implement this method or return @c nil,
the standard version comparator will be used.
Note that the standard version comparator may be used during installation for preventing a downgrade,
even if you provide a custom comparator here.
@param updater The updater instance.
@return The custom version comparator or @c nil if you don't want to be delegated this task.
*/
- (nullable id<SUVersionComparison>)versionComparatorForUpdater:(SPUUpdater *)updater __deprecated_msg("Custom version comparators are deprecated because they are incompatible with how the system compares different versions of an app.");
/**
Called when a background update will be scheduled after a delay.
Automatic update checks need to be enabled for this to trigger.
@param delay The delay in seconds until the next scheduled update will occur. This is an approximation and may vary due to system state.
@param updater The updater instance.
*/
- (void)updater:(SPUUpdater *)updater willScheduleUpdateCheckAfterDelay:(NSTimeInterval)delay;
/**
Called when no update checks will be scheduled in the future.
This may later change if automatic update checks become enabled.
@param updater The updater instance.
*/
- (void)updaterWillNotScheduleUpdateCheck:(SPUUpdater *)updater;
/**
Returns the decryption password (if any) which is used to extract the update archive DMG.
Return @c nil if no password should be used.
@param updater The updater instance.
@return The password used for decrypting the archive, or @c nil if no password should be used.
*/
- (nullable NSString *)decryptionPasswordForUpdater:(SPUUpdater *)updater;
/**
Called when an update is scheduled to be silently installed on quit after downloading the update automatically.
If the updater is given responsibility, it can later remind the user an update is available if they have not terminated the application for a long time.
Also if the updater is given responsibility and the update item is marked critical, the new update will be presented to the user immediately after.
Even if the @c immediateInstallHandler is not invoked, the installer will attempt to install the update on termination.
@param updater The updater instance.
@param item The appcast item corresponding to the update that is proposed to be installed.
@param immediateInstallHandler The install handler for the delegate to immediately install the update. No UI interaction will be shown and the application will be relaunched after installation. This handler can only be used if @c YES is returned and the delegate handles installing the update. For Sparkle 2.3 onwards, this handler can be invoked multiple times in case the application cancels the termination request.
@return @c YES if the delegate will handle installing the update or @c NO if the updater should be given responsibility.
*/
- (BOOL)updater:(SPUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationBlock:(void (^)(void))immediateInstallHandler;
/**
Called after the update driver aborts due to an error.
The update driver runs when checking for updates. This delegate method is called an error occurs during this process.
Some special possible values of `error.code` are:
- `SUNoUpdateError`: No new update was found.
- `SUInstallationCanceledError`: The user canceled installing the update when requested for authorization.
@param updater The updater instance.
@param error The error that caused the update driver to abort.
*/
- (void)updater:(SPUUpdater *)updater didAbortWithError:(NSError *)error;
/**
Called after the update driver finishes.
The update driver runs when checking for updates. This delegate method is called when that check is finished.
An update may be scheduled to be installed during the update cycle, or no updates may be found, or an available update may be dismissed or skipped (which is the same as no error).
If the @c error is @c nil, no error has occurred.
Some special possible values of `error.code` are:
- `SUNoUpdateError`: No new update was found.
- `SUInstallationCanceledError`: The user canceled installing the update when requested for authorization.
@param updater The updater instance.
@param updateCheck The type of update check was performed.
@param error The error that caused the update driver to abort. This is @c nil if the update driver finished normally and there is no error.
*/
- (void)updater:(SPUUpdater *)updater didFinishUpdateCycleForUpdateCheck:(SPUUpdateCheck)updateCheck error:(nullable NSError *)error;
/* Deprecated methods */
- (BOOL)updaterMayCheckForUpdates:(SPUUpdater *)updater __deprecated_msg("Please use -[SPUUpdaterDelegate updater:mayPerformUpdateCheck:error:] instead.");
- (void)updater:(SPUUpdater *)updater userDidSkipThisVersion:(SUAppcastItem *)item __deprecated_msg("Please use -[SPUUpdaterDelegate updater:userDidMakeChoice:forUpdate:state:] instead.");
@end
NS_ASSUME_NONNULL_END

View file

@ -1,69 +0,0 @@
//
// SPUUpdaterSettings.h
// Sparkle
//
// Created by Mayur Pawashe on 3/27/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
This class can be used for reading certain updater settings.
It retrieves the settings by first looking into the host's user defaults.
If the setting is not found in there, then the host's Info.plist file is looked at.
*/
SU_EXPORT @interface SPUUpdaterSettings : NSObject
- (instancetype)initWithHostBundle:(NSBundle *)hostBundle;
/**
* Indicates whether or not automatic update checks are enabled.
*/
@property (readonly, nonatomic) BOOL automaticallyChecksForUpdates;
/**
* The regular update check interval.
*/
@property (readonly, nonatomic) NSTimeInterval updateCheckInterval;
/**
* Indicates whether or not automatically downloading updates is allowed to be turned on by the user.
* If this value is nil, the developer has not explicitly specified this option.
*/
@property (readonly, nonatomic, nullable) NSNumber *allowsAutomaticUpdatesOption;
/**
* Indicates whether or not automatically downloading updates is allowed to be turned on by the user.
*/
@property (readonly, nonatomic) BOOL allowsAutomaticUpdates;
/**
* Indicates whether or not automatically downloading updates is enabled by the user or developer.
*
* Note this does not indicate whether or not automatic downloading of updates is allowable.
* See `-allowsAutomaticUpdates` property for that.
*/
@property (readonly, nonatomic) BOOL automaticallyDownloadsUpdates;
/**
* Indicates whether or not anonymous system profile information is sent when checking for updates.
*/
@property (readonly, nonatomic) BOOL sendsSystemProfile;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,300 +0,0 @@
//
// SPUUserDriver.h
// Sparkle
//
// Created by Mayur Pawashe on 2/14/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SPUUserUpdateState.h"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SPUUserUpdateState.h>
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SPUUpdatePermissionRequest, SUUpdatePermissionResponse, SUAppcastItem, SPUDownloadData;
/**
The API in Sparkle for controlling the user interaction.
This protocol is used for implementing a user interface for the Sparkle updater. Sparkle's internal drivers tell
an object that implements this protocol what actions to take and show to the user.
Every method in this protocol can be assumed to be called from the main thread.
*/
SU_EXPORT @protocol SPUUserDriver <NSObject>
/**
* Show an updater permission request to the user
*
* Ask the user for their permission regarding update checks.
* This is typically only called once per app installation.
*
* @param request The update permission request.
* @param reply A reply with a update permission response.
*/
- (void)showUpdatePermissionRequest:(SPUUpdatePermissionRequest *)request reply:(void (^)(SUUpdatePermissionResponse *))reply;
/**
* Show the user initiating an update check
*
* Respond to the user initiating an update check. Sparkle uses this to show the user a window with an indeterminate progress bar.
*
* @param cancellation Invoke this cancellation block to cancel the update check before the update check is completed.
*/
- (void)showUserInitiatedUpdateCheckWithCancellation:(void (^)(void))cancellation;
/**
* Show the user a new update is found.
*
* Let the user know a new update is found and ask them what they want to do.
* Before this point, `-showUserInitiatedUpdateCheckWithCancellation:` may be called.
*
* The potential `stage`s on the updater @c state are:
*
* `SPUUpdateStateNotDownloaded` - Update has not been downloaded yet.
*
* `SPUUpdateStateDownloaded` - Update has already been downloaded in the background automatically (via `SUAutomaticallyUpdate`) but not started installing yet.
*
* `SPUUpdateStateInstalling` - Update has been downloaded and already started installing.
*
* The `userInitiated` property on the @c state indicates if the update was initiated by the user or if it was automatically scheduled in the background.
*
* Additionally, these properties on the @c appcastItem are of importance:
*
* @c appcastItem.informationOnlyUpdate indicates if the update is only informational and should not be downloaded. You can direct the user to the infoURL property of the appcastItem in their web browser. Sometimes information only updates are used as a fallback in case a bad update is shipped, so you'll want to support this case.
*
* @c appcastItem.majorUpgrade indicates if the update is a major or paid upgrade.
*
* @c appcastItem.criticalUpdate indicates if the update is a critical update.
*
* A reply of `SPUUserUpdateChoiceInstall` begins or resumes downloading, extracting, or installing the update.
* If the state.stage is `SPUUserUpdateStateInstalling`, this may send a quit event to the application and relaunch it immediately (in this state, this behaves as a fast "install and Relaunch").
* If the state.stage is `SPUUpdateStateNotDownloaded` or `SPUUpdateStateDownloaded` the user may be presented an authorization prompt to install the update after `-showDownloadDidStartExtractingUpdate` is called if authorization is required for installation. For example, this may occur if the update on disk is owned by a different user (e.g. root or admin for non-admin users), or if the update is a package install.
* Do not use a reply of `SPUUserUpdateChoiceInstall` if @c appcastItem.informationOnlyUpdate is YES.
*
* A reply of `SPUUserUpdateChoiceDismiss` dismisses the update for the time being. The user may be reminded of the update at a later point.
* If the state.stage is `SPUUserUpdateStateDownloaded`, the downloaded update is kept after dismissing until the next time an update is shown to the user.
* If the state.stage is `SPUUserUpdateStateInstalling`, the installing update is also preserved after dismissing. In this state however, the update will also still be installed after the application is terminated.
*
* A reply of `SPUUserUpdateChoiceSkip` skips this particular version and won't notify the user again, unless they initiate an update check themselves.
* If @c appcastItem.majorUpgrade is YES, the major update and any future minor updates to that major release are skipped, unless a future minor update specifies a `<sparkle:ignoreSkippedUpgradesBelowVersion>` requirement.
* If the state.stage is `SPUUpdateStateInstalling`, the installation is also canceled when the update is skipped.
*
* @param appcastItem The Appcast Item containing information that reflects the new update.
* @param state The current state of the user update. See above discussion for notable properties.
* @param reply The reply which indicates if the update should be installed, dismissed, or skipped. See above discussion for more details.
*/
- (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply;
/**
* Show the user the release notes for the new update
*
* Display the release notes to the user. This will be called after showing the new update.
* This is only applicable if the release notes are linked from the appcast, and are not directly embedded inside of the appcast file.
* That is, this may be invoked if the releaseNotesURL from the appcast item is non-nil.
*
* @param downloadData The data for the release notes that was downloaded from the new update's appcast.
*/
- (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData;
/**
* Show the user that the new update's release notes could not be downloaded
*
* This will be called after showing the new update.
* This is only applicable if the release notes are linked from the appcast, and are not directly embedded inside of the appcast file.
* That is, this may be invoked if the releaseNotesURL from the appcast item is non-nil.
*
* @param error The error associated with why the new update's release notes could not be downloaded.
*/
- (void)showUpdateReleaseNotesFailedToDownloadWithError:(NSError *)error;
/**
* Show the user a new update was not found
*
* Let the user know a new update was not found after they tried initiating an update check.
* Before this point, `-showUserInitiatedUpdateCheckWithCancellation:` may be called.
*
* There are various reasons a new update is unavailable and can't be installed.
* The @c error object is populated with recovery and suggestion strings suitable to be shown in an alert.
*
* The @c userInfo dictionary on the @c error is also populated with two keys:
*
* `SPULatestAppcastItemFoundKey`: if available, this may provide the latest SUAppcastItem that was found.
*
* `SPUNoUpdateFoundReasonKey`: if available, this will provide the `SUNoUpdateFoundReason`. For example the reason could be because
* the latest version in the feed requires a newer OS version or could be because the user is already on the latest version.
*
* @param error The error associated with why a new update was not found. See above discussion for more details.
* @param acknowledgement Acknowledge to the updater that no update found error was shown.
*/
- (void)showUpdateNotFoundWithError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user an update error occurred
*
* Let the user know that the updater failed with an error. This will not be invoked without the user having been
* aware that an update was in progress.
*
* Before this point, any of the non-error user driver methods may have been invoked.
*
* @param error The error associated with what update error occurred.
* @param acknowledgement Acknowledge to the updater that the error was shown.
*/
- (void)showUpdaterError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user that downloading the new update initiated
*
* Let the user know that downloading the new update started.
*
* @param cancellation Invoke this cancellation block to cancel the download at any point before `-showDownloadDidStartExtractingUpdate` is invoked.
*/
- (void)showDownloadInitiatedWithCancellation:(void (^)(void))cancellation;
/**
* Show the user the content length of the new update that will be downloaded
*
* @param expectedContentLength The expected content length of the new update being downloaded.
* An implementor should be able to handle if this value is invalid (more or less than actual content length downloaded).
* Additionally, this method may be called more than once for the same download in rare scenarios.
*/
- (void)showDownloadDidReceiveExpectedContentLength:(uint64_t)expectedContentLength;
/**
* Show the user that the update download received more data
*
* This may be an appropriate time to advance a visible progress indicator of the download
* @param length The length of the data that was just downloaded
*/
- (void)showDownloadDidReceiveDataOfLength:(uint64_t)length;
/**
* Show the user that the update finished downloading and started extracting
*
* Sparkle uses this to show an indeterminate progress bar.
*
* Before this point, `showDownloadDidReceiveDataOfLength:` or `showUpdateFoundWithAppcastItem:state:reply:` may be called.
* An update can potentially resume at this point after having been automatically downloaded in the background (without the user driver) before.
*
* After extraction starts, the user may be shown an authorization prompt to install the update if authorization is required for installation.
* For example, this may occur if the update on disk is owned by a different user (e.g. root or admin for non-admin users), or if the update is a package install.
*/
- (void)showDownloadDidStartExtractingUpdate;
/**
* Show the user that the update is extracting with progress
*
* Let the user know how far along the update extraction is.
*
* Before this point, `-showDownloadDidStartExtractingUpdate` is called.
*
* @param progress The progress of the extraction from a 0.0 to 1.0 scale
*/
- (void)showExtractionReceivedProgress:(double)progress;
/**
* Show the user that the update is ready to install & relaunch
*
* Let the user know that the update is ready to install and relaunch, and ask them whether they want to proceed.
* Note if the target application has already terminated, this method may not be invoked.
*
* A reply of `SPUUserUpdateChoiceInstall` installs the update the new update immediately. The application is relaunched only if it is still running by the time this reply is invoked. If the application terminates on its own, Sparkle will attempt to automatically install the update.
*
* A reply of `SPUUserUpdateChoiceDismiss` dismisses the update installation for the time being. Note the update may still be installed automatically after the application terminates.
*
* A reply of `SPUUserUpdateChoiceSkip` cancels the current update that has begun installing and dismisses the update. In this circumstance, the update is canceled but this update version is not skipped in the future.
*
* Before this point, `-showExtractionReceivedProgress:` or `-showUpdateFoundWithAppcastItem:state:reply:` may be called.
*
* @param reply The reply which indicates if the update should be installed, dismissed, or skipped. See above discussion for more details.
*/
- (void)showReadyToInstallAndRelaunch:(void (^)(SPUUserUpdateChoice))reply;
/**
* Show the user that the update is installing
*
* Let the user know that the update is currently installing.
*
* Before this point, `-showReadyToInstallAndRelaunch:` or `-showUpdateFoundWithAppcastItem:state:reply:` will be called.
*
* @param applicationTerminated Indicates if the application has been terminated already.
* If the application hasn't been terminated, a quit event is sent to the running application before installing the update.
* If the application or user delays or cancels termination, there may be an indefinite period of time before the application fully quits.
* It is up to the implementor whether or not to decide to continue showing installation progress in this case.
*
* @param retryTerminatingApplication This handler gives a chance for the application to re-try sending a quit event to the running application before installing the update.
* The application may cancel or delay termination. This handler gives the user driver another chance to allow the user to try terminating the application again.
* If the application does not delay or cancel application termination, there is no need to invoke this handler. This handler may be invoked multiple times.
* Note this handler should not be invoked if @c applicationTerminated is already @c YES
*/
- (void)showInstallingUpdateWithApplicationTerminated:(BOOL)applicationTerminated retryTerminatingApplication:(void (^)(void))retryTerminatingApplication;
/**
* Show the user that the update installation finished
*
* Let the user know that the update finished installing.
*
* This will only be invoked if the updater process is still alive, which is typically not the case if
* the updater's lifetime is tied to the application it is updating. This implementation must not try to reference
* the old bundle prior to the installation, which will no longer be around.
*
* Before this point, `-showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication:` will be called.
*
* @param relaunched Indicates if the update was relaunched.
* @param acknowledgement Acknowledge to the updater that the finished installation was shown.
*/
- (void)showUpdateInstalledAndRelaunched:(BOOL)relaunched acknowledgement:(void (^)(void))acknowledgement;
/**
* Show the user the current presented update or its progress in utmost focus
*
* The user wishes to check for updates while the user is being shown update progress.
* Bring whatever is on screen to frontmost focus (permission request, update information, downloading or extraction status, choice to install update, etc).
*/
- (void)showUpdateInFocus;
/**
* Dismiss the current update installation
*
* Stop and tear down everything.
* Dismiss all update windows, alerts, progress, etc from the user.
* Basically, stop everything that could have been started. Sparkle may invoke this when aborting or finishing an update.
*/
- (void)dismissUpdateInstallation;
/*
* Below are deprecated methods that have been replaced by better alternatives.
* The deprecated methods will be used if the alternatives have not been implemented yet.
* In the future support for using these deprecated methods may be removed however.
*/
@optional
// Clients should move to non-deprecated methods
// Deprecated methods are only (temporarily) kept around for compatibility reasons
- (void)showUpdateNotFoundWithAcknowledgement:(void (^)(void))acknowledgement __deprecated_msg("Implement -showUpdateNotFoundWithError:acknowledgement: instead");
- (void)showUpdateInstallationDidFinishWithAcknowledgement:(void (^)(void))acknowledgement __deprecated_msg("Implement -showUpdateInstalledAndRelaunched:acknowledgement: instead");
- (void)dismissUserInitiatedUpdateCheck __deprecated_msg("Transition to new UI appropriately when a new update is shown, when no update is found, or when an update error occurs.");
- (void)showInstallingUpdate __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");
- (void)showSendingTerminationSignal __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");
- (void)showInstallingUpdateWithApplicationTerminated:(BOOL)applicationTerminated __deprecated_msg("Implement -showInstallingUpdateWithApplicationTerminated:retryTerminatingApplication: instead.");;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,85 +0,0 @@
//
// SPUUserUpdateState.h
// Sparkle
//
// Created by Mayur Pawashe on 2/29/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#ifndef SPUUserUpdateState_h
#define SPUUserUpdateState_h
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
A choice made by the user when prompted with a new update.
*/
typedef NS_ENUM(NSInteger, SPUUserUpdateChoice) {
/**
Dismisses the update and skips being notified of it in the future.
*/
SPUUserUpdateChoiceSkip,
/**
Downloads (if needed) and installs the update.
*/
SPUUserUpdateChoiceInstall,
/**
Dismisses the update until Sparkle reminds the user of it at a later time.
*/
SPUUserUpdateChoiceDismiss,
};
/**
Describes the current stage an update is undergoing.
*/
typedef NS_ENUM(NSInteger, SPUUserUpdateStage) {
/**
The update has not been downloaded.
*/
SPUUserUpdateStageNotDownloaded,
/**
The update has already been downloaded but not begun installing.
*/
SPUUserUpdateStageDownloaded,
/**
The update has already been downloaded and began installing in the background.
*/
SPUUserUpdateStageInstalling
};
/**
This represents the user's current update state.
*/
SU_EXPORT @interface SPUUserUpdateState : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
The current update stage.
This stage indicates if data has been already downloaded or not, or if an update is currently being installed.
*/
@property (nonatomic, readonly) SPUUserUpdateStage stage;
/**
Indicates whether or not the update check was initiated by the user.
*/
@property (nonatomic, readonly) BOOL userInitiated;
@end
NS_ASSUME_NONNULL_END
#endif /* SPUUserUpdateState_h */

View file

@ -1,45 +0,0 @@
//
// SUAppcast.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUAPPCAST_H
#define SUAPPCAST_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SUAppcastItem;
/**
The appcast representing a collection of `SUAppcastItem` items in the feed.
*/
SU_EXPORT @interface SUAppcast : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
The collection of update items.
These `SUAppcastItem` items are in the same order as specified in the appcast XML feed and are thus not sorted by version.
*/
@property (readonly, nonatomic, copy) NSArray<SUAppcastItem *> *items;
@end
NS_ASSUME_NONNULL_END
#endif

View file

@ -1,406 +0,0 @@
//
// SUAppcastItem.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUAPPCASTITEM_H
#define SUAPPCASTITEM_H
#import <Foundation/Foundation.h>
#ifdef BUILDING_SPARKLE_SOURCES_EXTERNALLY
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
The appcast item describing an update in the application's appcast feed.
An appcast item represents a single update item in the `SUAppcast` contained within the @c <item> element.
Every appcast item must have a `versionString`, and either a `fileURL` or an `infoURL`.
All the remaining properties describing an update to the application are optional.
Extended documentation and examples on using appcast item features are available at:
https://sparkle-project.org/documentation/publishing/
*/
SU_EXPORT @interface SUAppcastItem : NSObject<NSSecureCoding>
/**
The version of the update item.
Sparkle uses this property to compare update items and determine the best available update item in the `SUAppcast`.
This corresponds to the application update's @c CFBundleVersion
This is extracted from the @c <sparkle:version> element, or the @c sparkle:version attribute from the @c <enclosure> element.
*/
@property (nonatomic, copy, readonly) NSString *versionString;
/**
The human-readable display version of the update item if provided.
This is the version string shown to the user when they are notified of a new update.
This corresponds to the application update's @c CFBundleShortVersionString
This is extracted from the @c <sparkle:shortVersionString> element, or the @c sparkle:shortVersionString attribute from the @c <enclosure> element.
If no short version string is available, this falls back to the update's `versionString`.
*/
@property (nonatomic, copy, readonly) NSString *displayVersionString;
/**
The file URL to the update item if provided.
This download contains the actual update Sparkle will attempt to install.
In cases where a download cannot be provided, an `infoURL` must be provided instead.
A file URL should have an accompanying `contentLength` provided.
This is extracted from the @c url attribute in the @c <enclosure> element.
*/
@property (nonatomic, readonly, nullable) NSURL *fileURL;
/**
The content length of the download in bytes.
This property is used as a fallback when the server doesn't report the content length of the download.
In that case, it is used to report progress of the downloading update to the user.
A warning is outputted if this property is not equal the server's expected content length (if provided).
This is extracted from the @c length attribute in the @c <enclosure> element.
It should be specified if a `fileURL` is provided.
*/
@property (nonatomic, readonly) uint64_t contentLength;
/**
The info URL to the update item if provided.
This informational link is used to direct the user to learn more about an update they cannot download/install directly from within the application.
The link should point to the product's web page.
The informational link will be used if `informationOnlyUpdate` is @c YES
This is extracted from the @c <link> element.
*/
@property (nonatomic, readonly, nullable) NSURL *infoURL;
/**
Indicates whether or not the update item is only informational and has no download.
If `infoURL` is not present, this is @c NO
If `fileURL` is not present, this is @c YES
Otherwise this is determined based on the contents extracted from the @c <sparkle:informationalUpdate> element.
*/
@property (nonatomic, getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate;
/**
The title of the appcast item if provided.
This is extracted from the @c <title> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *title;
/**
The date string of the appcast item if provided.
The `date` property is constructed from this property and expects this string to comply with the following date format:
`E, dd MMM yyyy HH:mm:ss Z`
This is extracted from the @c <pubDate> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *dateString;
/**
The date constructed from the `dateString` property if provided.
Sparkle by itself only uses this property for phased group rollouts specified via `phasedRolloutInterval`, but clients may query this property too.
This date is constructed using the @c en_US locale.
*/
@property (nonatomic, copy, readonly, nullable) NSDate *date;
/**
The release notes URL of the appcast item if provided.
This external link points to an HTML file that Sparkle downloads and renders to show the user a new or old update item's changelog.
An alternative to using an external release notes link is providing an embedded `itemDescription`.
This is extracted from the @c <sparkle:releaseNotesLink> element.
*/
@property (nonatomic, readonly, nullable) NSURL *releaseNotesURL;
/**
The description of the appcast item if provided.
A description may be provided for inline/embedded release notes for new updates using @c <![CDATA[...]]>
This is an alternative to providing a `releaseNotesURL`.
This is extracted from the @c <description> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *itemDescription;
/**
The format of the `itemDescription` for inline/embedded release notes if provided.
This may be:
- @c html
- @c plain-text
This is extracted from the @c sparkle:descriptionFormat attribute in the @c <description> element.
If the format is not provided in the @c <description> element of the appcast item, then this property may default to `html`.
If the @c <description> element of the appcast item is not available, this property is `nil`.
*/
@property (nonatomic, readonly, nullable) NSString *itemDescriptionFormat;
/**
The full release notes URL of the appcast item if provided.
The link should point to the product's full changelog.
Sparkle's standard user interface offers to show these full release notes when a user checks for a new update and no new update is available.
This is extracted from the @c <sparkle:fullReleaseNotesLink> element.
*/
@property (nonatomic, readonly, nullable) NSURL *fullReleaseNotesURL;
/**
The required minimum system operating version string for this update if provided.
This version string should contain three period-separated components.
Example: @c 10.13.0
Use `minimumOperatingSystemVersionIsOK` property to test if the current running system passes this requirement.
This is extracted from the @c <sparkle:minimumSystemVersion> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *minimumSystemVersion;
/**
Indicates whether or not the current running system passes the `minimumSystemVersion` requirement.
*/
@property (nonatomic, readonly) BOOL minimumOperatingSystemVersionIsOK;
/**
The required maximum system operating version string for this update if provided.
A maximum system operating version requirement should only be made in unusual scenarios.
This version string should contain three period-separated components.
Example: @c 10.14.0
Use `maximumOperatingSystemVersionIsOK` property to test if the current running system passes this requirement.
This is extracted from the @c <sparkle:maximumSystemVersion> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *maximumSystemVersion;
/**
Indicates whether or not the current running system passes the `maximumSystemVersion` requirement.
*/
@property (nonatomic, readonly) BOOL maximumOperatingSystemVersionIsOK;
/**
The channel the update item is on if provided.
An update item may specify a custom channel name (such as @c beta) that can only be found by updaters that filter for that channel.
If no channel is provided, the update item is assumed to be on the default channel.
This is extracted from the @c <sparkle:channel> element.
Old applications must be using Sparkle 2 or later to interpret the channel element and to ignore unmatched channels.
*/
@property (nonatomic, readonly, nullable) NSString *channel;
/**
The installation type of the update at `fileURL`
This may be:
- @c application - indicates this is a regular application update.
- @c package - indicates this is a guided package installer update.
- @c interactive-package - indicates this is an interactive package installer update (deprecated; use "package" instead)
This is extracted from the @c sparkle:installationType attribute in the @c <enclosure> element.
If no installation type is provided in the enclosure, the installation type is inferred from the `fileURL` file extension instead.
If the file extension is @c pkg or @c mpkg, the installation type is @c package otherwise it is @c application
Hence, the installation type in the enclosure element only needs to be specified for package based updates distributed inside of a @c zip or other archive format.
Old applications must be using Sparkle 1.26 or later to support downloading bare package updates (`pkg` or `mpkg`) that are not additionally archived inside of a @c zip or other archive format.
*/
@property (nonatomic, copy, readonly) NSString *installationType;
/**
The phased rollout interval of the update item in seconds if provided.
This is the interval between when different groups of users are notified of a new update.
For this property to be used by Sparkle, the published `date` on the update item must be present as well.
After each interval after the update item's `date`, a new group of users become eligible for being notified of the new update.
This is extracted from the @c <sparkle:phasedRolloutInterval> element.
Old applications must be using Sparkle 1.25 or later to support phased rollout intervals, otherwise they may assume updates are immediately available.
*/
@property (nonatomic, copy, readonly, nullable) NSNumber* phasedRolloutInterval;
/**
The minimum bundle version string this update requires for automatically downloading and installing updates if provided.
If an application's bundle version meets this version requirement, it can install the new update item in the background automatically.
Otherwise if the requirement is not met, the user is always prompted to install the update. In this case, the update is assumed to be a `majorUpgrade`.
If the update is a `majorUpgrade` and the update is skipped by the user, other future update alerts with the same `minimumAutoupdateVersion` will also be skipped automatically unless an update specifies `ignoreSkippedUpgradesBelowVersion`.
This version string corresponds to the application's @c CFBundleVersion
This is extracted from the @c <sparkle:minimumAutoupdateVersion> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *minimumAutoupdateVersion;
/**
Indicates whether or not the update item is a major upgrade.
An update is a major upgrade if the application's bundle version doesn't meet the `minimumAutoupdateVersion` requirement.
*/
@property (nonatomic, getter=isMajorUpgrade, readonly) BOOL majorUpgrade;
/**
Previously skipped upgrades by the user will be ignored if they skipped an update whose version precedes this version.
This can only be applied if the update is a `majorUpgrade`.
This version string corresponds to the application's @c CFBundleVersion
This is extracted from the @c <sparkle:ignoreSkippedUpgradesBelowVersion> element.
Old applications must be using Sparkle 2.1 or later, otherwise this property will be ignored.
*/
@property (nonatomic, readonly, nullable) NSString *ignoreSkippedUpgradesBelowVersion;
/**
Indicates whether or not the update item is critical.
Critical updates are shown to the user more promptly. Sparkle's standard user interface also does not allow them to be skipped.
This is determined and extracted from a top-level @c <sparkle:criticalUpdate> element or a @c sparkle:criticalUpdate element inside of a @c sparkle:tags element.
Old applications must be using Sparkle 2 or later to support the top-level @c <sparkle:criticalUpdate> element.
*/
@property (nonatomic, getter=isCriticalUpdate, readonly) BOOL criticalUpdate;
/**
Specifies the operating system the download update is available for if provided.
If this property is not provided, then the supported operating system is assumed to be macOS.
Known potential values for this string are @c macos and @c windows
Sparkle on Mac ignores update items that are for other operating systems.
This is only useful for sharing appcasts between Sparkle on Mac and Sparkle on other operating systems.
Use `macOsUpdate` property to test if this update item is for macOS.
This is extracted from the @c sparkle:os attribute in the @c <enclosure> element.
*/
@property (nonatomic, copy, readonly, nullable) NSString *osString;
/**
Indicates whether or not this update item is for macOS.
This is determined from the `osString` property.
*/
@property (nonatomic, getter=isMacOsUpdate, readonly) BOOL macOsUpdate;
/**
The delta updates for this update item.
Sparkle uses these to download and apply a smaller update based on the version the user is updating from.
The key is based on the @c sparkle:version of the update.
The value is an update item that will have `deltaUpdate` be @c YES
Clients typically should not need to examine the contents of the delta updates.
This is extracted from the @c <sparkle:deltas> element.
*/
@property (nonatomic, copy, readonly, nullable) NSDictionary<NSString *, SUAppcastItem *> *deltaUpdates;
/**
The expected size of the Sparkle executable file before applying this delta update.
This attribute is used to test if the delta item can still be applied. If Sparkle's executable file has changed (e.g. from having an architecture stripped),
then the delta item cannot be applied.
This is extracted from the @c sparkle:deltaFromSparkleExecutableSize attribute from the @c <enclosure> element of a @c sparkle:deltas item.
This attribute is optional for delta update items.
*/
@property (nonatomic, nonatomic, readonly, nullable) NSNumber *deltaFromSparkleExecutableSize;
/**
An expected set of Sparkle's locales present on disk before applying this delta update.
This attribute is used to test if the delta item can still be applied. If Sparkle's list of locales present on disk (.lproj directories) do not contain any items from this set,
(e.g. from having localization files stripped) then the delta item cannot be applied. This set does not need to be a complete list of locales. Sparkle may even decide
to not process all them. 1-10 should be a decent amount.
This is extracted from the @c sparkle:deltaFromSparkleLocales attribute from the @c <enclosure> element of a @c sparkle:deltas item.
The locales extracted from this attribute are delimited by a comma (e.g. "en,ca,fr,hr,hu"). This attribute is optional for delta update items.
*/
@property (nonatomic, nonatomic, readonly, nullable) NSSet<NSString *> *deltaFromSparkleLocales;
/**
Indicates whether or not the update item is a delta update.
An update item is a delta update if it is in the `deltaUpdates` of another update item.
*/
@property (nonatomic, getter=isDeltaUpdate, readonly) BOOL deltaUpdate;
/**
The dictionary representing the entire appcast item.
This is useful for querying custom extensions or elements from the appcast item.
*/
@property (nonatomic, readonly, copy) NSDictionary *propertiesDictionary;
- (instancetype)init NS_UNAVAILABLE;
/**
An empty appcast item.
This may be used as a potential return value in `-[SPUUpdaterDelegate bestValidUpdateInAppcast:forUpdater:]`
*/
+ (instancetype)emptyAppcastItem;
// Deprecated initializers
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict relativeToURL:(NSURL * _Nullable)appcastURL failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error __deprecated_msg("Properties that depend on the system or application version are not supported when used with this initializer. The designated initializer is available in SUAppcastItem+Private.h. Please first explore other APIs or contact us to describe your use case.");
@end
NS_ASSUME_NONNULL_END
#endif

View file

@ -1,107 +0,0 @@
//
// SUErrors.h
// Sparkle
//
// Created by C.W. Betts on 10/13/14.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#ifndef SUERRORS_H
#define SUERRORS_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
/**
* Error domain used by Sparkle
*/
SU_EXPORT extern NSString *const SUSparkleErrorDomain;
typedef NS_ENUM(OSStatus, SUError) {
// Configuration phase errors
SUNoPublicDSAFoundError = 0001,
SUInsufficientSigningError = 0002,
SUInsecureFeedURLError = 0003,
SUInvalidFeedURLError = 0004,
SUInvalidUpdaterError = 0005,
SUInvalidHostBundleIdentifierError = 0006,
SUInvalidHostVersionError = 0007,
// Appcast phase errors.
SUAppcastParseError = 1000,
SUNoUpdateError = 1001,
SUAppcastError = 1002,
SURunningFromDiskImageError = 1003,
SUResumeAppcastError = 1004,
SURunningTranslocated = 1005,
SUWebKitTerminationError = 1006,
SUReleaseNotesError = 1007,
// Download phase errors.
SUTemporaryDirectoryError = 2000,
SUDownloadError = 2001,
// Extraction phase errors.
SUUnarchivingError = 3000,
SUSignatureError = 3001,
SUValidationError = 3002,
// Installation phase errors.
SUFileCopyFailure = 4000,
SUAuthenticationFailure = 4001,
SUMissingUpdateError = 4002,
SUMissingInstallerToolError = 4003,
SURelaunchError = 4004,
SUInstallationError = 4005,
SUDowngradeError = 4006,
SUInstallationCanceledError = 4007,
SUInstallationAuthorizeLaterError = 4008,
SUNotValidUpdateError = 4009,
SUAgentInvalidationError = 4010,
SUInstallationRootInteractiveError = 4011,
SUInstallationWriteNoPermissionError = 4012,
// API misuse errors.
SUIncorrectAPIUsageError = 5000
};
/**
The reason why a new update is not available.
*/
typedef NS_ENUM(OSStatus, SPUNoUpdateFoundReason) {
/**
A new update is unavailable for an unknown reason.
*/
SPUNoUpdateFoundReasonUnknown,
/**
A new update is unavailable because the user is on the latest known version in the appcast feed.
*/
SPUNoUpdateFoundReasonOnLatestVersion,
/**
A new update is unavailable because the user is on a version newer than the latest known version in the appcast feed.
*/
SPUNoUpdateFoundReasonOnNewerThanLatestVersion,
/**
A new update is unavailable because the user's operating system version is too old for the update.
*/
SPUNoUpdateFoundReasonSystemIsTooOld,
/**
A new update is unavailable because the user's operating system version is too new for the update.
*/
SPUNoUpdateFoundReasonSystemIsTooNew
};
SU_EXPORT extern NSString *const SPUNoUpdateFoundReasonKey;
SU_EXPORT extern NSString *const SPULatestAppcastItemFoundKey;
SU_EXPORT extern NSString *const SPUNoUpdateFoundUserInitiatedKey;
#endif

View file

@ -1,18 +0,0 @@
//
// SUExport.h
// Sparkle
//
// Created by Jake Petroules on 2014-08-23.
// Copyright (c) 2014 Sparkle Project. All rights reserved.
//
#ifndef SUEXPORT_H
#define SUEXPORT_H
#ifdef BUILDING_SPARKLE
#define SU_EXPORT __attribute__((visibility("default")))
#else
#define SU_EXPORT
#endif
#endif

View file

@ -1,63 +0,0 @@
//
// SUStandardVersionComparator.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef SUSTANDARDVERSIONCOMPARATOR_H
#define SUSTANDARDVERSIONCOMPARATOR_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SUVersionComparisonProtocol.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
Sparkle's default version comparator.
This comparator is adapted from MacPAD, by Kevin Ballard.
It's "dumb" in that it does essentially string comparison,
in components split by character type.
*/
SU_EXPORT @interface SUStandardVersionComparator : NSObject <SUVersionComparison>
/**
Initializes a new instance of the standard version comparator.
*/
- (instancetype)init;
/**
A singleton instance of the comparator.
*/
@property (nonatomic, class, readonly) SUStandardVersionComparator *defaultComparator;
/**
Compares two version strings through textual analysis.
These version strings should be in the format of x, x.y, or x.y.z where each component is a number.
For example, valid version strings include "1.5.3", "500", or "4000.1"
These versions that are compared correspond to the @c CFBundleVersion values of the updates.
@param versionA The first version string to compare.
@param versionB The second version string to compare.
@return A comparison result between @c versionA and @c versionB
*/
- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB;
@end
NS_ASSUME_NONNULL_END
#endif

View file

@ -1,73 +0,0 @@
//
// SUUpdatePermissionResponse.h
// Sparkle
//
// Created by Mayur Pawashe on 2/8/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
This class represents a response for permission to check updates.
*/
SU_EXPORT @interface SUUpdatePermissionResponse : NSObject<NSSecureCoding>
/**
Initializes a new update permission response instance.
@param automaticUpdateChecks Flag to enable automatic update checks.
@param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast.
*/
- (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks sendSystemProfile:(BOOL)sendSystemProfile;
/**
Initializes a new update permission response instance.
@param automaticUpdateChecks Flag to enable automatic update checks.
@param automaticUpdateDownloading Flag to enable automatic downloading and installing of updates. If this is nil, this option will be ignored.
@param sendSystemProfile Flag for if system profile information should be sent to the server hosting the appcast.
*/
- (instancetype)initWithAutomaticUpdateChecks:(BOOL)automaticUpdateChecks automaticUpdateDownloading:(NSNumber * _Nullable)automaticUpdateDownloading sendSystemProfile:(BOOL)sendSystemProfile;
/*
Use -initWithAutomaticUpdateChecks:sendSystemProfile: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/**
A read-only property indicating if update checks should be done automatically.
*/
@property (nonatomic, readonly) BOOL automaticUpdateChecks;
/**
A read-only property indicating if updates should be automatically downloaded and installed.
If this property is `nil`, then no user choice was made for this option.
If `automaticUpdateChecks` is `NO` then this property should not be `@(YES)`.
Set it to `NO` if the user was given the choice of automatically downloading and installing updates,
otherwise set it to `nil`.
*/
@property (nonatomic, readonly, nullable) NSNumber *automaticUpdateDownloading;
/**
A read-only property indicating if system profile should be sent or not.
*/
@property (nonatomic, readonly) BOOL sendSystemProfile;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,212 +0,0 @@
//
// SUUpdater.h
// Sparkle
//
// Created by Andy Matuschak on 1/4/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SUUPDATER_H
#define SUUPDATER_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SUVersionComparisonProtocol.h"
#import "SUVersionDisplayProtocol.h"
#import "SUUpdaterDelegate.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUVersionDisplayProtocol.h>
#import <Sparkle/SUUpdaterDelegate.h>
#endif
@class SUAppcastItem, SUAppcast, NSMenuItem;
@protocol SUUpdaterDelegate;
/**
The legacy API in Sparkle for controlling the update mechanism.
This class is now deprecated and acts as a thin wrapper around `SPUUpdater` and `SPUStandardUserDriver`.
If you are migrating to Sparkle 2, use `SPUStandardUpdaterController` instead, or `SPUUpdater` if you need more control.
*/
__deprecated_msg("Deprecated in Sparkle 2. Use SPUStandardUpdaterController instead, or SPUUpdater if you need more control.")
SU_EXPORT @interface SUUpdater : NSObject
@property (unsafe_unretained, nonatomic) IBOutlet id<SUUpdaterDelegate> delegate;
/*!
The shared updater for the main bundle.
This is equivalent to passing [NSBundle mainBundle] to SUUpdater::updaterForBundle:
*/
+ (SUUpdater *)sharedUpdater;
/*!
The shared updater for a specified bundle.
If an updater has already been initialized for the provided bundle, that shared instance will be returned.
*/
+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle;
/*!
Designated initializer for SUUpdater.
If an updater has already been initialized for the provided bundle, that shared instance will be returned.
*/
- (instancetype)initForBundle:(NSBundle *)bundle;
/*!
Explicitly checks for updates and displays a progress dialog while doing so.
This method is meant for a main menu item.
Connect any menu item to this action in Interface Builder,
and Sparkle will check for updates and report back its findings verbosely
when it is invoked.
This will find updates that the user has opted into skipping.
*/
- (IBAction)checkForUpdates:(id)sender;
/*!
The menu item validation used for the -checkForUpdates: action
*/
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
/*!
Checks for updates, but does not display any UI unless an update is found.
This is meant for programmatically initiating a check for updates. That is,
it will display no UI unless it actually finds an update, in which case it
proceeds as usual.
If automatic downloading of updates it turned on and allowed, however,
this will invoke that behavior, and if an update is found, it will be downloaded
in the background silently and will be prepped for installation.
This will not find updates that the user has opted into skipping.
*/
- (void)checkForUpdatesInBackground;
/*!
A property indicating whether or not to check for updates automatically.
Setting this property will persist in the host bundle's user defaults.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) BOOL automaticallyChecksForUpdates;
/*!
A property indicating whether or not updates can be automatically downloaded in the background.
Note that automatic downloading of updates can be disallowed by the developer.
In this case, -automaticallyDownloadsUpdates will return NO regardless of how this property is set.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL automaticallyDownloadsUpdates;
/*!
A property indicating the current automatic update check interval.
Setting this property will persist in the host bundle's user defaults.
The update schedule cycle will be reset in a short delay after the property's new value is set.
This is to allow reverting this property without kicking off a schedule change immediately
*/
@property (nonatomic) NSTimeInterval updateCheckInterval;
/*!
Begins a "probing" check for updates which will not actually offer to
update to that version.
However, the delegate methods
SUUpdaterDelegate::updater:didFindValidUpdate: and
SUUpdaterDelegate::updaterDidNotFindUpdate: will be called,
so you can use that information in your UI.
Updates that have been skipped by the user will not be found.
*/
- (void)checkForUpdateInformation;
/*!
The URL of the appcast used to download update information.
Setting this property will persist in the host bundle's user defaults.
If you don't want persistence, you may want to consider instead implementing
SUUpdaterDelegate::feedURLStringForUpdater: or SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile:
This property must be called on the main thread.
*/
@property (nonatomic, copy) NSURL *feedURL;
/*!
The host bundle that is being updated.
*/
@property (readonly, nonatomic) NSBundle *hostBundle;
/*!
The bundle this class (SUUpdater) is loaded into.
*/
@property (nonatomic, readonly) NSBundle *sparkleBundle;
/*!
The user agent used when checking for and downloading updates.
The default implementation can be overridden.
*/
@property (nonatomic, copy) NSString *userAgentString;
/*!
The HTTP headers used when checking for and downloading updates.
The keys of this dictionary are HTTP header fields (NSString) and values are corresponding values (NSString)
*/
@property (copy, nonatomic) NSDictionary<NSString *, NSString *> *httpHeaders;
/*!
A property indicating whether or not the user's system profile information is sent when checking for updates.
Setting this property will persist in the host bundle's user defaults.
*/
@property (nonatomic) BOOL sendsSystemProfile;
/*!
A property indicating the decryption password used for extracting updates shipped as Apple Disk Images (dmg)
*/
@property (nonatomic, copy) NSString *decryptionPassword;
/*!
Returns the date of last update check.
\returns \c nil if no check has been performed.
*/
@property (nonatomic, readonly, copy) NSDate *lastUpdateCheckDate;
/*!
Appropriately schedules or cancels the update checking timer according to
the preferences for time interval and automatic checks.
This call does not change the date of the next check,
but only the internal NSTimer.
*/
- (void)resetUpdateCycle;
/*!
A property indicating whether or not an update is in progress.
Note this property is not indicative of whether or not user initiated updates can be performed.
Use SUUpdater::validateMenuItem: for that instead.
*/
@property (nonatomic, readonly) BOOL updateInProgress;
@end
#endif

View file

@ -1,363 +0,0 @@
//
// SUUpdaterDelegate.h
// Sparkle
//
// Created by Mayur Pawashe on 3/12/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
@protocol SUVersionComparison, SUVersionDisplay;
@class SUUpdater, SUAppcast, SUAppcastItem;
NS_ASSUME_NONNULL_BEGIN
// -----------------------------------------------------------------------------
// SUUpdater Notifications for events that might be interesting to more than just the delegate
// The updater will be the notification object
// -----------------------------------------------------------------------------
SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
// -----------------------------------------------------------------------------
// SUUpdater Delegate:
// -----------------------------------------------------------------------------
/*!
Provides methods to control the behavior of an SUUpdater object.
*/
__deprecated_msg("Deprecated in Sparkle 2. See SPUUpdaterDelegate instead")
@protocol SUUpdaterDelegate <NSObject>
@optional
/*!
Returns whether to allow Sparkle to pop up.
For example, this may be used to prevent Sparkle from interrupting a setup assistant.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)updater;
/*!
Returns additional parameters to append to the appcast URL's query string.
This is potentially based on whether or not Sparkle will also be sending along the system profile.
\param updater The SUUpdater instance.
\param sendingProfile Whether the system profile will also be sent.
\return An array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user.
*/
- (NSArray<NSDictionary<NSString *, NSString *> *> *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;
/*!
Returns a custom appcast URL.
Override this to dynamically specify the entire URL.
An alternative may be to use SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile:
and let the server handle what kind of feed to provide.
\param updater The SUUpdater instance.
*/
- (nullable NSString *)feedURLStringForUpdater:(SUUpdater *)updater;
/*!
Returns whether Sparkle should prompt the user about automatic update checks.
Use this to override the default behavior.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)updater;
/*!
Called after Sparkle has downloaded the appcast from the remote server.
Implement this if you want to do some special handling with the appcast once it finishes loading.
\param updater The SUUpdater instance.
\param appcast The appcast that was downloaded from the remote server.
*/
- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
/*!
Returns the item in the appcast corresponding to the update that should be installed.
If you're using special logic or extensions in your appcast,
implement this to use your own logic for finding a valid update, if any,
in the given appcast.
\param appcast The appcast that was downloaded from the remote server.
\param updater The SUUpdater instance.
*/
- (nullable SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater;
/*!
Called when a valid update is found by the update driver.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item;
/*!
Called when a valid update is not found.
\param updater The SUUpdater instance.
*/
- (void)updaterDidNotFindUpdate:(SUUpdater *)updater;
/*!
Called just before the scheduled update driver prompts the user to install an update.
\param updater The SUUpdater instance.
\return YES to allow the update prompt to be shown (the default behavior), or NO to suppress it.
*/
- (BOOL)updaterShouldShowUpdateAlertForScheduledUpdate:(SUUpdater *)updater forItem:(SUAppcastItem *)item;
/*!
Called after the user dismisses the update alert.
\param updater The SUUpdater instance.
\param permanently YES if the alert will not appear again for this update; NO if it may reappear.
*/
- (void)updater:(SUUpdater *)updater didDismissUpdateAlertPermanently:(BOOL)permanently forItem:(SUAppcastItem *)item;
/*!
Called immediately before downloading the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be downloaded.
\param request The mutable URL request that will be used to download the update.
*/
- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request;
/*!
Called immediately after successful download of the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that has been downloaded.
*/
- (void)updater:(SUUpdater *)updater didDownloadUpdate:(SUAppcastItem *)item;
/*!
Called after the specified update failed to download.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that failed to download.
\param error The error generated by the failed download.
*/
- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error;
/*!
Called when the user clicks the cancel button while and update is being downloaded.
\param updater The SUUpdater instance.
*/
- (void)userDidCancelDownload:(SUUpdater *)updater;
/*!
Called immediately before extracting the specified downloaded update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be extracted.
*/
- (void)updater:(SUUpdater *)updater willExtractUpdate:(SUAppcastItem *)item;
/*!
Called immediately after extracting the specified downloaded update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that has been extracted.
*/
- (void)updater:(SUUpdater *)updater didExtractUpdate:(SUAppcastItem *)item;
/*!
Called immediately before installing the specified update.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item;
/*!
Called when an update is skipped by the user.
\param updater The updater instance.
\param item The appcast item corresponding to the update that the user skipped.
*/
- (void)updater:(SUUpdater *)updater userDidSkipThisVersion:(SUAppcastItem *)item;
/*!
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This may also not be called if the application is not going to relaunch after it terminates.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param invocation The invocation that must be completed with `[invocation invoke]` before continuing with the relaunch.
\return \c YES to delay the relaunch until \p invocation is invoked.
*/
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvoking:(NSInvocation *)invocation;
/*!
Returns whether the relaunch should be delayed in order to perform other tasks.
This is not called if the user didn't relaunch on the previous update,
in that case it will immediately restart.
This method acts as a simpler alternative to SUUpdaterDelegate::updater:shouldPostponeRelaunchForUpdate:untilInvoking: avoiding usage of NSInvocation, which is not available in Swift environments.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\return \c YES to delay the relaunch.
*/
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item;
/*!
Returns whether the application should be relaunched at all.
Some apps \b cannot be relaunched under certain circumstances.
This method can be used to explicitly prevent a relaunch.
\param updater The SUUpdater instance.
*/
- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater;
/*!
Called immediately before relaunching.
\param updater The SUUpdater instance.
*/
- (void)updaterWillRelaunchApplication:(SUUpdater *)updater;
/*!
Called immediately after relaunching. SUUpdater delegate must be set before applicationDidFinishLaunching: to catch this event.
\param updater The SUUpdater instance.
*/
- (void)updaterDidRelaunchApplication:(SUUpdater *)updater;
/*!
Returns an object that compares version numbers to determine their arithmetic relation to each other.
This method allows you to provide a custom version comparator.
If you don't implement this method or return \c nil,
the standard version comparator will be used. Note that the
standard version comparator may be used during installation for preventing
a downgrade, even if you provide a custom comparator here.
\sa SUStandardVersionComparator
\param updater The SUUpdater instance.
*/
- (nullable id<SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater;
/*!
Returns an object that formats version numbers for display to the user.
If you don't implement this method or return \c nil, the standard version formatter will be used.
\sa SUUpdateAlert
\param updater The SUUpdater instance.
*/
- (nullable id <SUVersionDisplay>)versionDisplayerForUpdater:(SUUpdater *)updater;
/*!
Returns the path to the application which is used to relaunch after the update is installed.
The installer also waits for the termination of the application at this path.
The default is the path of the host bundle.
\param updater The SUUpdater instance.
*/
- (nullable NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater;
/*!
Called before an updater shows a modal alert window,
to give the host the opportunity to hide attached windows that may get in the way.
\param updater The SUUpdater instance.
*/
- (void)updaterWillShowModalAlert:(SUUpdater *)updater;
/*!
Called after an updater shows a modal alert window,
to give the host the opportunity to hide attached windows that may get in the way.
\param updater The SUUpdater instance.
*/
- (void)updaterDidShowModalAlert:(SUUpdater *)updater;
/*!
Called when an update is scheduled to be silently installed on quit.
This is after an update has been automatically downloaded in the background.
(i.e. SUUpdater::automaticallyDownloadsUpdates is YES)
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param invocation Can be used to trigger an immediate silent install and relaunch.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation;
/*!
Called when an update is scheduled to be silently installed on quit.
This is after an update has been automatically downloaded in the background.
(i.e. SUUpdater::automaticallyDownloadsUpdates is YES)
This method acts as a more modern alternative to SUUpdaterDelegate::updater:willInstallUpdateOnQuit:immediateInstallationInvocation: using a block instead of NSInvocation, which is not available in Swift environments.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that is proposed to be installed.
\param installationBlock Can be used to trigger an immediate silent install and relaunch.
*/
- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationBlock:(void (^)(void))installationBlock;
/*!
Calls after an update that was scheduled to be silently installed on quit has been canceled.
\param updater The SUUpdater instance.
\param item The appcast item corresponding to the update that was proposed to be installed.
\deprecated This method is no longer invoked. The installer will try to its best ability to install the update.
*/
- (void)updater:(SUUpdater *)updater didCancelInstallUpdateOnQuit:(SUAppcastItem *)item __deprecated;
/*!
Called after an update is aborted due to an error.
\param updater The SUUpdater instance.
\param error The error that caused the abort
*/
- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,42 +0,0 @@
//
// SUVersionComparisonProtocol.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef SUVERSIONCOMPARISONPROTOCOL_H
#define SUVERSIONCOMPARISONPROTOCOL_H
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
/**
Provides version comparison facilities for Sparkle.
*/
@protocol SUVersionComparison
/**
An abstract method to compare two version strings.
Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a,
and NSOrderedSame if they are equivalent.
*/
- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD!
@end
NS_ASSUME_NONNULL_END
#endif

View file

@ -1,78 +0,0 @@
//
// SUVersionDisplayProtocol.h
// EyeTV
//
// Created by Uli Kusterer on 08.12.09.
// Copyright 2009 Elgato Systems GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
@class SUAppcastItem;
NS_ASSUME_NONNULL_BEGIN
/**
Applies special display formatting to version numbers of the bundle to update and the update before presenting them to the user.
*/
SU_EXPORT @protocol SUVersionDisplay <NSObject>
/**
Formats an update's version string and bundle's version string for display.
This method is used to format both the display version of the update and the display version of the bundle to update.
The display versions returned by this method are then used for presenting to the user when a new update is available,
or when the user cannot download/install the latest update for a specific reason, or when the user has a newer version
installed than the latest known version in the update feed.
On input, the `update.displayVersionString` and `*inOutBundleDisplayVersion` may be the same, but the
`update.versionString` and `bundleVersion` will differ. To differentiate between these display versions, you may
choose to return different display version strings for the update and bundle.
@param update The update to format the update display version from. You can query `update.displayVersionString` and `update.versionString` to retrieve the update's version information.
@param inOutBundleDisplayVersion On input, the display version string (or `CFBundleShortVersionString`) of the bundle to update. On output, this is the display version string of the bundle to show to the user.
@param bundleVersion The version (or CFBundleVersion) of the bundle to update.
@return A new display version string of the `update.displayVersionString` to show to the user.
*/
- (NSString *)formatUpdateDisplayVersionFromUpdate:(SUAppcastItem *)update andBundleDisplayVersion:(NSString * _Nonnull __autoreleasing * _Nonnull)inOutBundleDisplayVersion withBundleVersion:(NSString *)bundleVersion;
@optional
/**
Formats a bundle's version string for display.
This method is used to format the display version of the bundle.
This method may be used when no new update is available and the user is already on the latest known version.
In this case, no new update version is shown to the user.
This method is optional. If it's not implemented, Sparkle will default to using the `bundleDisplayVersion` passed to this method.
@param bundleDisplayVersion The display version string (or `CFBundleShortVersionString`) of the bundle to update.
@param bundleVersion The version (or `CFBundleVersion`) of the bundle to update.
@param matchingUpdate The update in the feed that corresponds to the current bundle, or `nil` if no matching update item could be found in the feed.
@return A new display version string of the bundle to show to the user.
*/
- (NSString *)formatBundleDisplayVersion:(NSString *)bundleDisplayVersion withBundleVersion:(NSString *)bundleVersion matchingUpdate:(SUAppcastItem * _Nullable)matchingUpdate;
/**
Formats two version strings.
Both versions are provided so that important distinguishing information
can be displayed while also leaving out unnecessary/confusing parts.
*/
- (void)formatVersion:(NSString *_Nonnull*_Nonnull)inOutVersionA andVersion:(NSString *_Nonnull*_Nonnull)inOutVersionB __deprecated_msg("Please use -formatUpdateDisplayVersionFromUpdate:andBundleDisplayVersion:withBundleVersion:");
@end
NS_ASSUME_NONNULL_END

View file

@ -1,39 +0,0 @@
//
// Sparkle.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07)
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#ifndef SPARKLE_H
#define SPARKLE_H
// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless
// there are name-space collisions) so we can list all of them to start with:
#import <Sparkle/SUExport.h>
#import <Sparkle/SUAppcast.h>
#import <Sparkle/SUAppcastItem.h>
#import <Sparkle/SUStandardVersionComparator.h>
#import <Sparkle/SPUUpdater.h>
#import <Sparkle/SPUUpdaterDelegate.h>
#import <Sparkle/SPUUpdaterSettings.h>
#import <Sparkle/SUVersionComparisonProtocol.h>
#import <Sparkle/SUVersionDisplayProtocol.h>
#import <Sparkle/SUErrors.h>
#import <Sparkle/SPUUpdatePermissionRequest.h>
#import <Sparkle/SUUpdatePermissionResponse.h>
#import <Sparkle/SPUUserDriver.h>
#import <Sparkle/SPUDownloadData.h>
// UI bits
#import <Sparkle/SPUStandardUpdaterController.h>
#import <Sparkle/SPUStandardUserDriver.h>
#import <Sparkle/SPUStandardUserDriverDelegate.h>
// Deprecated bits
#import <Sparkle/SUUpdater.h>
#import <Sparkle/SUUpdaterDelegate.h>
#endif

View file

@ -1,6 +0,0 @@
framework module Sparkle {
umbrella header "Sparkle.h"
export *
module * { export * }
}

View file

@ -1,38 +0,0 @@
//
// SPUAppcastItemStateResolver.h
// Sparkle
//
// Created by Mayur Pawashe on 5/31/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SUStandardVersionComparator, SPUAppcastItemState;
@protocol SUVersionComparison;
/**
Private exposed class used to resolve Appcast Item properties that rely on external factors such as a host.
This resolver is used for constructing appcast items.
*/
SU_EXPORT @interface SPUAppcastItemStateResolver : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithHostVersion:(NSString *)hostVersion applicationVersionComparator:(id<SUVersionComparison>)applicationVersionComparator standardVersionComparator:(SUStandardVersionComparator *)standardVersionComparator;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,22 +0,0 @@
//
// SPUGentleUserDriverReminders.h
// Sparkle
//
// Copyright © 2022 Sparkle Project. All rights reserved.
//
#ifndef SPUGentleUserDriverReminders_h
#define SPUGentleUserDriverReminders_h
/**
A private protocol for user drivers implementing gentle scheduled reminders
*/
@protocol SPUGentleUserDriverReminders
- (void)logGentleScheduledUpdateReminderWarningIfNeeded;
- (void)resetTimeSinceOpportuneUpdateNotice;
@end
#endif /* SPUGentleUserDriverReminders_h */

View file

@ -1,19 +0,0 @@
//
// SPUInstallationType.h
// Sparkle
//
// Created by Mayur Pawashe on 7/24/16.
// Copyright © 2016 Sparkle Project. All rights reserved.
//
#ifndef SPUInstallationType_h
#define SPUInstallationType_h
#define SPUInstallationTypeApplication @"application" // the default installation type for ordinary application updates
#define SPUInstallationTypeGuidedPackage @"package" // the preferred installation type for package installations
#define SPUInstallationTypeInteractivePackage @"interactive-package" // the deprecated installation type; use guided package instead
#define SPUInstallationTypesArray (@[SPUInstallationTypeApplication, SPUInstallationTypeGuidedPackage, SPUInstallationTypeInteractivePackage])
#define SPUValidInstallationType(x) ((x != nil) && [SPUInstallationTypesArray containsObject:(NSString * _Nonnull)x])
#endif /* SPUInstallationType_h */

View file

@ -1,40 +0,0 @@
//
// SPUStandardUserDriver+Private.h
// Sparkle
//
// Copyright © 2022 Sparkle Project. All rights reserved.
//
#ifndef SPUStandardUserDriver_Private_h
#define SPUStandardUserDriver_Private_h
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SPUStandardUserDriver.h"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SPUStandardUserDriver.h>
#import <Sparkle/SUExport.h>
#endif
@class NSWindowController;
NS_ASSUME_NONNULL_BEGIN
SU_EXPORT @interface SPUStandardUserDriver (Private)
/**
Private API for accessing the active update alert's window controller.
This is the window controller that shows the update's release notes and install choices.
This can be accessed in -[SPUStandardUserDriverDelegate standardUserDriverWillHandleShowingUpdate:forUpdate:state:]
*/
@property (nonatomic, readonly, nullable) NSWindowController *activeUpdateAlert;
@end
NS_ASSUME_NONNULL_END
#endif /* SPUStandardUserDriver_Private_h */

View file

@ -1,29 +0,0 @@
//
// SPUUserAgent+Private.h
// Sparkle
//
// Created by Mayur Pawashe on 11/12/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@class SUHost;
SU_EXPORT NSString *SPUMakeUserAgentWithHost(SUHost *responsibleHost, NSString * _Nullable displayNameSuffix);
SU_EXPORT NSString *SPUMakeUserAgentWithBundle(NSBundle *responsibleBundle, NSString * _Nullable displayNameSuffix);
NS_ASSUME_NONNULL_END

View file

@ -1,40 +0,0 @@
//
// SUAppcastItem+Private.h
// Sparkle
//
// Created by Mayur Pawashe on 4/30/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SUAppcastItem_Private_h
#define SUAppcastItem_Private_h
#import <Foundation/Foundation.h>
#import <Sparkle/SUAppcastItem.h>
NS_ASSUME_NONNULL_BEGIN
// Available in SPUAppcastItemStateResolver.h (a private exposed header)
@class SPUAppcastItemStateResolver;
@class SUSignatures;
@interface SUAppcastItem (Private) <NSSecureCoding>
/**
Initializes with data from a dictionary provided by the RSS class and state resolver
This initializer method is intended to be marked "private" and discouraged from public usage.
This method is available however. Talk to us to describe your use case and if you need to construct appcast items yourself.
*/
- (nullable instancetype)initWithDictionary:(NSDictionary *)dict relativeToURL:(NSURL * _Nullable)appcastURL stateResolver:(SPUAppcastItemStateResolver *)stateResolver failureReason:(NSString * _Nullable __autoreleasing *_Nullable)error;
/**
The EdDSA and DSA signatures along with their statuses.
*/
@property (readonly, nonatomic, nullable) SUSignatures *signatures;
@end
NS_ASSUME_NONNULL_END
#endif /* SUAppcastItem_Private_h */

View file

@ -1,37 +0,0 @@
//
// SUInstallerLauncher+Private.h
// SUInstallerLauncher+Private
//
// Created by Mayur Pawashe on 8/21/21.
// Copyright © 2021 Sparkle Project. All rights reserved.
//
#ifndef SUInstallerLauncher_Private_h
#define SUInstallerLauncher_Private_h
#if defined(BUILDING_SPARKLE_SOURCES_EXTERNALLY)
// Ignore incorrect warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
#import "SUExport.h"
#import "SPUInstallationType.h"
#pragma clang diagnostic pop
#else
#import <Sparkle/SUExport.h>
// Chances are clients will need this too
#import <Sparkle/SPUInstallationType.h>
#endif
@class NSString;
/**
Private API for determining if the system needs authorization access to update a bundle path
This API is not supported when used directly from a Sandboxed applications and will always return @c YES in that case.
@param bundlePath The bundle path to test if authorization is needed when performing an update that replaces this bundle.
@return @c YES if Sparkle thinks authorization is needed to update the @c bundlePath, otherwise @c NO.
*/
SU_EXPORT BOOL SPUSystemNeedsAuthorizationAccessForBundlePath(NSString *bundlePath);
#endif /* SUInstallerLauncher_Private_h */

View file

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>24C101</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>Sparkle</string>
<key>CFBundleIdentifier</key>
<string>org.sparkle-project.Sparkle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Sparkle</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.7.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>2044</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>24B75</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>15.1</string>
<key>DTSDKBuild</key>
<string>24B75</string>
<key>DTSDKName</key>
<string>macosx15.1</string>
<key>DTXcode</key>
<string>1610</string>
<key>DTXcodeBuild</key>
<string>16B40</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
</dict>
</plist>

View file

@ -1,13 +0,0 @@
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
color: white;
background: transparent;
}
:link {
color: #419CFF;
}
:link:active {
color: #FF1919;
}
}

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "محدث البرنامج";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "معلومات عن الإصدار:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "تذكيري لاحقًا";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "تخطي هذا الإصدار";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "تثبيت التحديث";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "تنزيل التحديثات وتثبيتها تلقائيًا في المستقبل";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "عدم التحقق";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "هل تريد أن يتم التحقق من وجود تحديثات تلقائيًا؟";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "تضمين تقرير عن النظام دون ذكر معلومات عن المستخدم";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "تنزيل التحديثات وتثبيتها تلقائيًا في المست";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "التحقق تلقائيًا";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Actualització del programari";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notes d'aquesta versió:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Recorda-m'ho més tard";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Omet aquesta versió";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instal·la l'actualització";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Descarrega i instal·la les actualitzacions automàticament en el futur";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Aktualizace aplikace";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Poznámky k vydání:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Připomenout později";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Přeskočit tuto verzi";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instalovat aktualizaci";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "V budoucnu stahovat a instalovat aktualizace automaticky";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Informace z anonymního systémového profilu pomáhají vývojářům lépe plánovat budoucí vývoj aplikace.\nBudete-li mít nějaký dotaz, obraťte se na nás.\n\nToto jsou informace, které budou odeslány:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nevyhledávat";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Vyhledávat aktualizace automaticky?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Odeslat anonymní systémový profil";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Stahovat a instalovat aktualizace automaticky";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automaticky vyhledávat";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Software Update";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Om denne udgivelse:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Påmind mig senere";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Spring over";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installer";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Hent og installer opdateringer automatisk i fremtiden";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Søg ikke";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Søg efter opdateringer automatisk?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Vedhæft anonym systemprofil";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Hent og installer opdateringer automatisk";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Søg automatisk";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Softwareupdate";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Versionshinweise:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Später erinnern";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Diese Version überspringen";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installieren";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Updates in Zukunft automatisch laden und installieren";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Das anonymisierte Systemprofil unterstützt uns bei der zukünftigen Entwicklung. Bitte kontaktiere uns, wenn du Fragen hierzu hast.\n\nDiese Informationen würden an uns gesendet werden:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nicht suchen";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Automatisch nach Updates suchen?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Anonymisiertes Systemprofil übertragen";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Updates automatisch laden und installieren";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automatisch suchen";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Ενημέρωση προγράμματος";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Σημειώσεις Έκδοσης:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Υπενθύμιση Αργότερα";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Παράλειψη Έκδοσης";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Εγκατάσταση Ενημέρωσης";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Αυτόματη λήψη και εγκατάσταση ενημερώσεων στο μέλλον";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Οι ανώνυμες πληροφορίες του προφίλ του συστήματός σας, μας βοηθούν στο σχεδιασμό της μελλοντικής ανάπτυξης του προγράμματος. Παρακαλώ επικοινωνήστε μαζί μας άν έχετε ερωτήσεις.\n\nΑυτές είναι οι πληροφορίες που θα σταλούν σε εμάς:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Κανένας έλεγχος";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Αυτόματος έλεγχος για ενημερώσεις;";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Συμπερίληψη του ανώνυμου προφίλ του συστήματός σας";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Αυτόματη λήψη και εγκατάσταση ενημερώσεων";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Αυτόματος Ελεγχος";

View file

@ -1,18 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Software Update";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Release Notes:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Remind Me Later";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Skip This Version";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Install Update";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Automatically download and install updates in the future";

View file

@ -1,27 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "176"; */
"OhZ-1K-DmA.title" = "Check Automatically";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "177"; */
"cCJ-V0-aTi.title" = "Dont Check";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "178"; */
"gmh-T4-BO0.title" = "Check for updates automatically?";
/* Class = "NSTextFieldCell"; title = "DO NOT LOCALIZE"; ObjectID = "179"; */
"179.title" = "DO NOT LOCALIZE";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "180"; */
"gz7-LM-gNf.title" = "Include anonymous system profile";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Automatically download and install updates";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Actualización de software";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notas de la versión:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Recordármelo";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "No instalar esta versión";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instalar actualización";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Descargar e instalar actualizaciones automáticamente";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "La información de perfil de sistema anónimo se usa para ayudarnos a planear el trabajo de desarrollo futuro. Por favor, póngase en contacto con nosotros si tiene preguntas sobre esto.\n\nEsta es la información que nos enviaría:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "No comprobar";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "¿Comprobar si hay actualizaciones automáticamente?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Incluir perfil de sistema anónimo";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Descargar e instalar actualizaciones automáticamente";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Comprobar automáticamente";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Ohjelmiston pävitys";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Tietoa päivityksestä:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Muistuta myöhemmin";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Ohita tämä versio";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Asenna päivitys";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Hae ja asenna päivitykset jatkossa automaattisesti";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Älä tarkista";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Tarkista päivitykset käynnistyksen yhteydessä?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Sisällytä nimetön järjestelmäprofiili";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Hae ja asenna päivitykset automaattisesti";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Tarkista automaattisesti";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Mise à jour logiciel";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Notes de version :";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Pas maintenant";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Ignorer cette version";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Installer";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Télécharger et installer automatiquement les mises à jour";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Les informations anonymes de profil système nous aident à planifier les futurs développements. Contactez-nous pour toute question à ce sujet.\n\nCi-dessous figurent les informations qui seront transmises :";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Ne pas vérifier";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Rechercher automatiquement les mises à jour ?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Avec transmission anonyme de mon profil système";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Télécharger et installer automatiquement les mises à jour";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Vérifier automatiquement";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "עדכון תוכנה";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "הערות שחרור:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "הזכר לי מאוחר יותר";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "דלג על גרסה זו";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "התקן את העדכון";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "הורד והתקן עדכונים בעתיד באופן אוטומטי";

View file

@ -1,27 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "176"; */
"OhZ-1K-DmA.title" = "חפש עדכונים אוטומטית";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "177"; */
"cCJ-V0-aTi.title" = "אל תחפש";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "178"; */
"gmh-T4-BO0.title" = "לחפש עדכונים באופן אוטומטי?";
/* Class = "NSTextFieldCell"; title = "DO NOT LOCALIZE"; ObjectID = "179"; */
"179.title" = "DO NOT LOCALIZE";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "180"; */
"gz7-LM-gNf.title" = "כלול מידע מערכת אנונימי";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "הורד והתקן עדכונים באופן אוטומטי";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "מידע מערכת אנונימי משמש כדי לעזור לנו לתכנן את עבודת הפיתוח העתידית. אנא צור איתנו קשר אם יש לך שאלות בנושא.\n\nזהו המידע שיישלח:";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Aktualiziranje softvera";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Napomene uz izdanje:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Podsjeti me kasnije";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Zanemari ovu verziju";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Instaliraj nadogradnju";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Ubuduće preuzmi i instaliraj nadogradnje automatski";

View file

@ -1,23 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonimizirani podaci profila susatava pomažu nam planirati budući razvoj. Kontaktiraj nas, ako imaš pitanja o tome.\n\nŠalju se sljedeći podaci:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Nemoj provjeravati";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Automatski provjeriti nadogradnje?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Uključi anonimizirane podatke o profilu sustava";
/* Class = "NSButtonCell"; title = "Automatically download and install updates"; ObjectID = "AUc-33-qGN"; */
"AUc-33-qGN.title" = "Preuzmi i instaliraj nadogradnje automatski";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Provjeri automatski";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Szoftverfrissítés";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Változások az előző verzióhoz képest:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Emlékeztessen később";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Verzió kihagyása";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Telepítés";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "A jövőben automatikusan töltse le és telepítse a frissítéseket";

View file

@ -1,20 +0,0 @@
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "43"; */
"43.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "45"; */
"45.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:"; ObjectID = "183"; */
"183.title" = "Anonymous system profile information is used to help us plan future development work. Please contact us if you have any questions about this.\n\nThis is the information that would be sent:";
/* Class = "NSButtonCell"; title = "Dont Check"; ObjectID = "cCJ-V0-aTi"; */
"cCJ-V0-aTi.title" = "Manuális keresés";
/* Class = "NSTextFieldCell"; title = "Check for updates automatically?"; ObjectID = "gmh-T4-BO0"; */
"gmh-T4-BO0.title" = "Keresse automatikusan a frissítéseket?";
/* Class = "NSButtonCell"; title = "Include anonymous system profile"; ObjectID = "gz7-LM-gNf"; */
"gz7-LM-gNf.title" = "Anonim rendszerinformáció küldése";
/* Class = "NSButtonCell"; title = "Check Automatically"; ObjectID = "OhZ-1K-DmA"; */
"OhZ-1K-DmA.title" = "Automatikus keresés";

View file

@ -1,17 +0,0 @@
/* Class = "NSWindow"; title = "Software Update"; ObjectID = "5"; */
"5.title" = "Hugbúnaðaruppfærsla";
/* Class = "NSTextFieldCell"; title = "Release Notes:"; ObjectID = "170"; */
"170.title" = "Útgáfupunktar:";
/* Class = "NSButtonCell"; title = "Remind Me Later"; ObjectID = "171"; */
"171.title" = "Áminntu mig síðar";
/* Class = "NSButtonCell"; title = "Skip This Version"; ObjectID = "172"; */
"172.title" = "Sleppa þessari útgáfu";
/* Class = "NSButtonCell"; title = "Install Update"; ObjectID = "173"; */
"173.title" = "Innsetja";
/* Class = "NSButtonCell"; title = "Automatically download and install updates in the future"; ObjectID = "175"; */
"175.title" = "Sækja og innsetja uppfærslur sjálfkrafa framvegis";

Some files were not shown because too many files have changed in this diff Show more