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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Enable processor usage profiling for the app to gather information for
potential bottleneck tracking.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Remove deprecated functions, make use of free functions that clear the
pointers before returning, etc.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Remove deprecated functions, make use of free functions that clear the
pointers before returning, etc.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>