Current section

Files

Jump to
rockbox_ffi src rockbox@player.erl
Raw

src/rockbox@player.erl

-module(rockbox@player).
-compile([no_auto_import, nowarn_ignored, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-export([default_config/0, eq_preset_to_int/1, channel_mode_to_int/1, crossfeed_mode_to_int/1, repeat_mode_to_int/1, repeat_mode_from_int/1, new/0, with_config/1, set_queue/2, insert/3, queue/1, enqueue/2, remove/2, clear_queue/1, play/1, pause/1, toggle/1, stop/1, next/1, previous/1, skip_to/2, seek_ms/2, set_volume/2, set_balance/2, volume/1, balance/1, sample_rate/1, set_crossfade/7, set_replaygain/4, status/1, set_shuffle/2, is_shuffle_enabled/1, set_repeat/2, repeat/1, set_eq_enabled/2, is_eq_enabled/1, set_eq_band/5, set_eq_precut/2, set_eq_preset/2, set_tone/5, set_bass/2, set_treble/2, set_surround/5, set_channel_mode/2, set_stereo_width/2, set_compressor/7, set_dither/2, set_pitch/2, set_bass_cutoff/2, set_treble_cutoff/2, set_crossfeed/6, set_bass_enhancement/3, set_fatigue_reduction/2, dsp_settings/1, resume/1, save_resume/1, clear_resume/1, load_resume/1, import_m3u/3, load_m3u/2, export_m3u/2, m3u_read/1, m3u_write/2, is_url/1]).
-export_type([player/0, insert_position/0, config/0, resume_state/0, m3u_entry/0, eq_preset/0, channel_mode/0, crossfeed_mode/0, repeat_mode/0, status/0, eq_band/0, equalizer/0, tone/0, surround/0, compressor/0, crossfeed/0, bass_enhancement/0, dsp_settings/0]).
-moduledoc(~" Queue-based player with native ReplayGain and Rockbox crossfade.
A `Player` owns a live audio output device and a background engine
thread, so it only works where an output device exists. The handle is a
NIF resource, freed by the BEAM garbage collector (which stops playback).
ReplayGain `mode` here uses the player values: 0 off, 1 track, 2 album.
Crossfade `mode`: 0 off, 1 auto-skip, 2 manual-skip, 3 shuffle,
4 shuffle-or-manual, 5 always. Mix mode: 0 crossfade, 1 mix.
Mutating functions return the `Player`, so they can be piped:
p
|> player.set_queue(tracks)
|> player.set_shuffle(True)
|> player.set_repeat(player.All)
|> player.play").
-type player() :: any().
-type insert_position() :: prepend | insert | insert_next | insert_last | insert_shuffled | insert_last_shuffled | replace | {index, integer()}.
-type config() :: {config, integer(), float(), float(), integer(), float(), boolean(), integer(), integer(), integer(), integer(), integer(), integer(), gleam@option:option(binary()), integer(), gleam@option:option(binary())}.
-type resume_state() :: {resume_state, list(binary()), integer(), integer()}.
-type m3u_entry() :: {m3u_entry, binary(), gleam@option:option(integer()), gleam@option:option(binary())}.
-type eq_preset() :: flat | acoustic | bass_boost | bass_reducer | classical | dance | deep | electronic | hip_hop | jazz | latin | loudness | lounge | piano | pop | rn_b | rock | small_speakers | treble_boost | treble_reducer | vocal_boost.
-type channel_mode() :: stereo | mono | custom | mono_left | mono_right | karaoke | swap.
-type crossfeed_mode() :: crossfeed_off | meier | crossfeed_custom.
-type repeat_mode() :: off | one | all.
-type status() :: {status, binary(), gleam@option:option(integer()), integer(), integer(), integer(), boolean(), binary()}.
-type eq_band() :: {eq_band, integer(), float(), float()}.
-type equalizer() :: {equalizer, boolean(), float(), list(eq_band())}.
-type tone() :: {tone, integer(), integer(), integer(), integer()}.
-type surround() :: {surround, integer(), integer(), integer(), integer()}.
-type compressor() :: {compressor, integer(), integer(), integer(), integer(), integer(), integer()}.
-type crossfeed() :: {crossfeed, binary(), integer(), integer(), integer(), integer()}.
-type bass_enhancement() :: {bass_enhancement, integer(), integer()}.
-type dsp_settings() :: {dsp_settings, equalizer(), tone(), surround(), binary(), integer(), compressor(), boolean(), integer(), crossfeed(), bass_enhancement(), integer()}.
-file("src/rockbox/player.gleam", 92).
-spec default_config() -> config().
-doc(~" Rockbox-default configuration (device sample rate, no crossfade,
ReplayGain off, full volume, resume disabled, default cpal output).").
default_config() ->
{config, 0, 4.0, 1.0, 0, +0.0, true, 0, 0, 2000, 0, 2000, 0, none, 0, none}.
-file("src/rockbox/player.gleam", 114).
-spec insert_position_args(insert_position()) -> {integer(), integer()}.
-doc(~" Encode an `InsertPosition` as the ABI's integer tag plus the index arg
(only meaningful for `Index`).").
insert_position_args(Position) ->
case Position of
prepend ->
{0, 0};
insert ->
{1, 0};
insert_next ->
{2, 0};
insert_last ->
{3, 0};
insert_shuffled ->
{4, 0};
insert_last_shuffled ->
{5, 0};
replace ->
{6, 0};
{index, I} ->
{7, I}
end.
-file("src/rockbox/player.gleam", 154).
-spec eq_preset_to_int(eq_preset()) -> integer().
-doc(~" Encode an `EqPreset` as the ABI's integer id (0..20).").
eq_preset_to_int(Preset) ->
case Preset of
flat ->
0;
acoustic ->
1;
bass_boost ->
2;
bass_reducer ->
3;
classical ->
4;
dance ->
5;
deep ->
6;
electronic ->
7;
hip_hop ->
8;
jazz ->
9;
latin ->
10;
loudness ->
11;
lounge ->
12;
piano ->
13;
pop ->
14;
rn_b ->
15;
rock ->
16;
small_speakers ->
17;
treble_boost ->
18;
treble_reducer ->
19;
vocal_boost ->
20
end.
-file("src/rockbox/player.gleam", 193).
-spec channel_mode_to_int(channel_mode()) -> integer().
-doc(~" Encode a `ChannelMode` as the ABI's integer id (0..6).").
channel_mode_to_int(Mode) ->
case Mode of
stereo ->
0;
mono ->
1;
custom ->
2;
mono_left ->
3;
mono_right ->
4;
karaoke ->
5;
swap ->
6
end.
-file("src/rockbox/player.gleam", 214).
-spec crossfeed_mode_to_int(crossfeed_mode()) -> integer().
-doc(~" Encode a `CrossfeedMode` as the ABI's integer id (0/1/2).").
crossfeed_mode_to_int(Mode) ->
case Mode of
crossfeed_off ->
0;
meier ->
1;
crossfeed_custom ->
2
end.
-file("src/rockbox/player.gleam", 231).
-spec repeat_mode_to_int(repeat_mode()) -> integer().
-doc(~" Encode a `RepeatMode` as the ABI's integer id (0/1/2).").
repeat_mode_to_int(Mode) ->
case Mode of
off ->
0;
one ->
1;
all ->
2
end.
-file("src/rockbox/player.gleam", 240).
-spec repeat_mode_from_int(integer()) -> repeat_mode().
-doc(~" Decode the ABI's integer id (0/1/2) into a `RepeatMode` (unknown → `Off`).").
repeat_mode_from_int(Value) ->
case Value of
1 ->
one;
2 ->
all;
_ ->
off
end.
-file("src/rockbox/player.gleam", 338).
-spec new() -> player().
-doc(~" Create a player on the default device with default settings.").
new() ->
rockbox_ffi_nif:player_new().
-file("src/rockbox/player.gleam", 343).
-spec with_config(config()) -> player().
-doc(~" Create a player with explicit configuration (including resume and the
audio output backend). See `Config` for the `output` spec strings and the
stdout-clean caveat.").
with_config(C) ->
Resume_file = case erlang:element(14, C) of
{some, Path} ->
gleam_stdlib:identity(Path);
none ->
gleam@dynamic:nil()
end,
case erlang:element(16, C) of
{some, Spec} ->
rockbox_ffi_nif:player_new_with_output(gleam_stdlib:identity(Spec), erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C), erlang:element(10, C), erlang:element(11, C), erlang:element(12, C), erlang:element(13, C), Resume_file, erlang:element(15, C));
none ->
rockbox_ffi_nif:player_new_with_config_ex(erlang:element(2, C), erlang:element(3, C), erlang:element(4, C), erlang:element(5, C), erlang:element(6, C), erlang:element(7, C), erlang:element(8, C), erlang:element(9, C), erlang:element(10, C), erlang:element(11, C), erlang:element(12, C), erlang:element(13, C), Resume_file, erlang:element(15, C))
end.
-file("src/rockbox/player.gleam", 393).
-spec set_queue(player(), list(binary())) -> player().
-doc(~" Replace the queue. Each entry may be a local file path, an `http(s)://`
URL to a finite remote file, or a live-radio / streaming URL.").
set_queue(Player, Paths) ->
rockbox_ffi_nif:player_set_queue_json(Player, erlang:iolist_to_binary(json:encode(Paths))),
Player.
-file("src/rockbox/player.gleam", 399).
-spec insert(player(), list(binary()), insert_position()) -> player().
-doc(~" Insert a list of paths / URLs into the queue at `position`.").
insert(Player, Paths, Position) ->
{Pos, Index} = insert_position_args(Position),
rockbox_ffi_nif:player_insert_json(Player, erlang:iolist_to_binary(json:encode(Paths)), Pos, Index),
Player.
-file("src/rockbox/player.gleam", 410).
-spec queue(player()) -> list(binary()).
-doc(~" The current queue as a list of paths / URLs.").
queue(Player) ->
case gleam@dynamic@decode:run(json:decode(rockbox_ffi_nif:player_queue_json(Player)), gleam@dynamic@decode:list({decoder, fun gleam@dynamic@decode:decode_string/1})) of
{ok, Paths} ->
Paths;
{error, _} ->
[]
end.
-file("src/rockbox/player.gleam", 419).
-spec enqueue(player(), binary()) -> player().
-doc(~" Append one track to the queue. `path` may be a local file path, an
`http(s)://` URL to a finite remote file, or a live-radio / streaming URL.").
enqueue(Player, Path) ->
rockbox_ffi_nif:player_enqueue(Player, Path),
Player.
-file("src/rockbox/player.gleam", 432).
-spec remove(player(), integer()) -> player().
-doc(~" Remove the track at zero-based `index` from the queue. An out-of-range
index is ignored. Removing a track before the current one keeps the current
track playing; removing the currently-playing track hard-cuts to the track
that slides into its place; removing the last remaining track stops
playback.").
remove(Player, Index) ->
rockbox_ffi_nif:player_remove(Player, Index),
Player.
-file("src/rockbox/player.gleam", 441).
-spec clear_queue(player()) -> player().
-doc(~" Empty the queue and stop playback (also clears any saved resume state).").
clear_queue(Player) ->
rockbox_ffi_nif:player_clear_queue(Player),
Player.
-file("src/rockbox/player.gleam", 450).
-spec play(player()) -> player().
-doc(~" Start (or resume) playback.").
play(Player) ->
rockbox_ffi_nif:player_play(Player),
Player.
-file("src/rockbox/player.gleam", 459).
-spec pause(player()) -> player().
-doc(~" Pause playback.").
pause(Player) ->
rockbox_ffi_nif:player_pause(Player),
Player.
-file("src/rockbox/player.gleam", 468).
-spec toggle(player()) -> player().
-doc(~" Toggle between play and pause.").
toggle(Player) ->
rockbox_ffi_nif:player_toggle(Player),
Player.
-file("src/rockbox/player.gleam", 477).
-spec stop(player()) -> player().
-doc(~" Stop playback.").
stop(Player) ->
rockbox_ffi_nif:player_stop(Player),
Player.
-file("src/rockbox/player.gleam", 486).
-spec next(player()) -> player().
-doc(~" Skip to the next track.").
next(Player) ->
rockbox_ffi_nif:player_next(Player),
Player.
-file("src/rockbox/player.gleam", 495).
-spec previous(player()) -> player().
-doc(~" Skip to the previous track.").
previous(Player) ->
rockbox_ffi_nif:player_previous(Player),
Player.
-file("src/rockbox/player.gleam", 504).
-spec skip_to(player(), integer()) -> player().
-doc(~" Skip to the track at `index` in the queue.").
skip_to(Player, Index) ->
rockbox_ffi_nif:player_skip_to(Player, Index),
Player.
-file("src/rockbox/player.gleam", 513).
-spec seek_ms(player(), integer()) -> player().
-doc(~" Seek to `ms` within the current track.").
seek_ms(Player, Ms) ->
rockbox_ffi_nif:player_seek_ms(Player, Ms),
Player.
-file("src/rockbox/player.gleam", 522).
-spec set_volume(player(), float()) -> player().
-doc(~" Set the output volume (0.0..1.0).").
set_volume(Player, Volume) ->
rockbox_ffi_nif:player_set_volume(Player, Volume),
Player.
-file("src/rockbox/player.gleam", 531).
-spec set_balance(player(), integer()) -> player().
-doc(~" Set the stereo balance, -100 (full left) to +100 (full right); 0 = centre.").
set_balance(Player, Balance) ->
rockbox_ffi_nif:player_set_balance(Player, Balance),
Player.
-file("src/rockbox/player.gleam", 540).
-spec volume(player()) -> float().
volume(Player) ->
rockbox_ffi_nif:player_volume(Player).
-file("src/rockbox/player.gleam", 544).
-spec balance(player()) -> integer().
-doc(~" Current stereo balance, -100 (full left) to +100 (full right).").
balance(Player) ->
rockbox_ffi_nif:player_balance(Player).
-file("src/rockbox/player.gleam", 547).
-spec sample_rate(player()) -> integer().
sample_rate(Player) ->
rockbox_ffi_nif:player_sample_rate(Player).
-file("src/rockbox/player.gleam", 550).
-spec set_crossfade(player(), integer(), integer(), integer(), integer(), integer(), integer()) -> player().
-doc(~" Configure crossfade behaviour.").
set_crossfade(Player, Mode, Fade_out_delay_ms, Fade_out_duration_ms, Fade_in_delay_ms, Fade_in_duration_ms, Mix_mode) ->
rockbox_ffi_nif:player_set_crossfade(Player, Mode, Fade_out_delay_ms, Fade_out_duration_ms, Fade_in_delay_ms, Fade_in_duration_ms, Mix_mode),
Player.
-file("src/rockbox/player.gleam", 583).
-spec set_replaygain(player(), integer(), float(), boolean()) -> player().
-doc(~" Configure ReplayGain (mode, pre-amp in dB, clipping prevention).").
set_replaygain(Player, Mode, Preamp_db, Prevent_clipping) ->
rockbox_ffi_nif:player_set_replaygain(Player, Mode, Preamp_db, Prevent_clipping),
Player.
-file("src/rockbox/player.gleam", 1024).
-spec status_decoder() -> gleam@dynamic@decode:decoder(status()).
status_decoder() ->
gleam@dynamic@decode:field(~"state", {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(State) ->
gleam@dynamic@decode:field(~"index", gleam@dynamic@decode:one_of(gleam@dynamic@decode:map({decoder, fun gleam@dynamic@decode:decode_int/1}, fun(_value) ->
{some, _value}
end), [gleam@dynamic@decode:success(none)]), fun(Index) ->
gleam@dynamic@decode:field(~"position_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Position_ms) ->
gleam@dynamic@decode:field(~"duration_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Duration_ms) ->
gleam@dynamic@decode:field(~"queue_len", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Queue_len) ->
gleam@dynamic@decode:field(~"shuffle", {decoder, fun gleam@dynamic@decode:decode_bool/1}, fun(Shuffle) ->
gleam@dynamic@decode:field(~"repeat", {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Repeat) ->
gleam@dynamic@decode:success({status, State, Index, Position_ms, Duration_ms, Queue_len, Shuffle, Repeat})
end)
end)
end)
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 602).
-spec status(player()) -> status().
-doc(~" A snapshot of the player's status.").
status(Player) ->
case gleam@dynamic@decode:run(json:decode(rockbox_ffi_nif:player_status_json(Player)), status_decoder()) of
{ok, Status} ->
Status;
_value ->
erlang:error(#{
gleam_error => let_assert,
message => ~"Pattern match failed, no pattern matched the value.",
file => ~"src/rockbox/player.gleam",
module => ~"rockbox/player",
function => ~"status",
line => 603,
value => _value,
start => 15482,
'end' => 15576,
pattern_start => 15493,
pattern_end => 15503
})
end.
-file("src/rockbox/player.gleam", 611).
-spec set_shuffle(player(), boolean()) -> player().
-doc(~" Enable or disable shuffle playback.").
set_shuffle(Player, Enabled) ->
rockbox_ffi_nif:player_set_shuffle(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 621).
-spec is_shuffle_enabled(player()) -> boolean().
-doc(~" Whether shuffle playback is currently enabled.").
is_shuffle_enabled(Player) ->
rockbox_ffi_nif:player_is_shuffle_enabled(Player).
-file("src/rockbox/player.gleam", 624).
-spec set_repeat(player(), repeat_mode()) -> player().
-doc(~" Set the repeat mode (off / one / all).").
set_repeat(Player, Mode) ->
rockbox_ffi_nif:player_set_repeat(Player, repeat_mode_to_int(Mode)),
Player.
-file("src/rockbox/player.gleam", 630).
-spec repeat(player()) -> repeat_mode().
-doc(~" The current repeat mode (off / one / all).").
repeat(Player) ->
repeat_mode_from_int(rockbox_ffi_nif:player_repeat(Player)).
-file("src/rockbox/player.gleam", 637).
-spec set_eq_enabled(player(), boolean()) -> player().
-doc(~" Enable or disable the graphic equalizer.").
set_eq_enabled(Player, Enabled) ->
rockbox_ffi_nif:player_set_eq_enabled(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 647).
-spec is_eq_enabled(player()) -> boolean().
-doc(~" Whether the graphic equalizer is currently enabled.").
is_eq_enabled(Player) ->
rockbox_ffi_nif:player_is_eq_enabled(Player).
-file("src/rockbox/player.gleam", 650).
-spec set_eq_band(player(), integer(), integer(), float(), float()) -> player().
-doc(~" Configure one EQ band: `cutoff_hz` in Hz, `q` factor, `gain_db` in dB.").
set_eq_band(Player, Band, Cutoff_hz, Q, Gain_db) ->
rockbox_ffi_nif:player_set_eq_band(Player, Band, Cutoff_hz, Q, Gain_db),
Player.
-file("src/rockbox/player.gleam", 671).
-spec set_eq_precut(player(), float()) -> player().
-doc(~" Set the EQ pre-cut (headroom), in dB.").
set_eq_precut(Player, Db) ->
rockbox_ffi_nif:player_set_eq_precut(Player, Db),
Player.
-file("src/rockbox/player.gleam", 680).
-spec set_eq_preset(player(), eq_preset()) -> player().
-doc(~" Apply a built-in EQ preset.").
set_eq_preset(Player, Preset) ->
rockbox_ffi_nif:player_set_eq_preset(Player, eq_preset_to_int(Preset)),
Player.
-file("src/rockbox/player.gleam", 686).
-spec set_tone(player(), integer(), integer(), integer(), integer()) -> player().
-doc(~" Set the bass/treble tone controls (gains in dB, cutoffs in Hz).").
set_tone(Player, Bass_db, Treble_db, Bass_cutoff_hz, Treble_cutoff_hz) ->
rockbox_ffi_nif:player_set_tone(Player, Bass_db, Treble_db, Bass_cutoff_hz, Treble_cutoff_hz),
Player.
-file("src/rockbox/player.gleam", 707).
-spec set_bass(player(), integer()) -> player().
-doc(~" Set the bass tone gain, in dB.").
set_bass(Player, Bass_db) ->
rockbox_ffi_nif:player_set_bass(Player, Bass_db),
Player.
-file("src/rockbox/player.gleam", 716).
-spec set_treble(player(), integer()) -> player().
-doc(~" Set the treble tone gain, in dB.").
set_treble(Player, Treble_db) ->
rockbox_ffi_nif:player_set_treble(Player, Treble_db),
Player.
-file("src/rockbox/player.gleam", 725).
-spec set_surround(player(), integer(), integer(), integer(), integer()) -> player().
-doc(~" Configure the surround effect (delay in ms, balance, cutoffs in Hz).").
set_surround(Player, Delay_ms, Balance, Cutoff_low_hz, Cutoff_high_hz) ->
rockbox_ffi_nif:player_set_surround(Player, Delay_ms, Balance, Cutoff_low_hz, Cutoff_high_hz),
Player.
-file("src/rockbox/player.gleam", 746).
-spec set_channel_mode(player(), channel_mode()) -> player().
-doc(~" Set the channel-mixing mode.").
set_channel_mode(Player, Mode) ->
rockbox_ffi_nif:player_set_channel_mode(Player, channel_mode_to_int(Mode)),
Player.
-file("src/rockbox/player.gleam", 752).
-spec set_stereo_width(player(), integer()) -> player().
-doc(~" Set the stereo width, as a percentage.").
set_stereo_width(Player, Percent) ->
rockbox_ffi_nif:player_set_stereo_width(Player, Percent),
Player.
-file("src/rockbox/player.gleam", 761).
-spec set_compressor(player(), integer(), integer(), integer(), integer(), integer(), integer()) -> player().
-doc(~" Configure the dynamic-range compressor.").
set_compressor(Player, Threshold_db, Makeup_gain, Ratio, Knee, Attack_ms, Release_ms) ->
rockbox_ffi_nif:player_set_compressor(Player, Threshold_db, Makeup_gain, Ratio, Knee, Attack_ms, Release_ms),
Player.
-file("src/rockbox/player.gleam", 794).
-spec set_dither(player(), boolean()) -> player().
-doc(~" Enable or disable output dithering.").
set_dither(Player, Enabled) ->
rockbox_ffi_nif:player_set_dither(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 803).
-spec set_pitch(player(), integer()) -> player().
-doc(~" Set the pitch ratio (Rockbox's fixed-point pitch value).").
set_pitch(Player, Ratio) ->
rockbox_ffi_nif:player_set_pitch(Player, Ratio),
Player.
-file("src/rockbox/player.gleam", 812).
-spec set_bass_cutoff(player(), integer()) -> player().
-doc(~" Set the bass tone cutoff frequency, in Hz.").
set_bass_cutoff(Player, Hz) ->
rockbox_ffi_nif:player_set_bass_cutoff(Player, Hz),
Player.
-file("src/rockbox/player.gleam", 821).
-spec set_treble_cutoff(player(), integer()) -> player().
-doc(~" Set the treble tone cutoff frequency, in Hz.").
set_treble_cutoff(Player, Hz) ->
rockbox_ffi_nif:player_set_treble_cutoff(Player, Hz),
Player.
-file("src/rockbox/player.gleam", 832).
-spec set_crossfeed(player(), crossfeed_mode(), integer(), integer(), integer(), integer()) -> player().
-doc(~" Configure the crossfeed (headphone) effect. `direct_gain`, `cross_gain`
and `high_freq_gain` are gains; `high_freq_cutoff` is in Hz. The gain
values only take effect in `CrossfeedCustom` mode.").
set_crossfeed(Player, Mode, Direct_gain, Cross_gain, High_freq_gain, High_freq_cutoff) ->
rockbox_ffi_nif:player_set_crossfeed(Player, crossfeed_mode_to_int(Mode), Direct_gain, Cross_gain, High_freq_gain, High_freq_cutoff),
Player.
-file("src/rockbox/player.gleam", 862).
-spec set_bass_enhancement(player(), integer(), integer()) -> player().
-doc(~" Configure bass enhancement (`strength` and `precut`).").
set_bass_enhancement(Player, Strength, Precut) ->
rockbox_ffi_nif:player_set_bass_enhancement(Player, Strength, Precut),
Player.
-file("src/rockbox/player.gleam", 875).
-spec set_fatigue_reduction(player(), integer()) -> player().
-doc(~" Set the listening-fatigue reduction strength.").
set_fatigue_reduction(Player, Strength) ->
rockbox_ffi_nif:player_set_fatigue_reduction(Player, Strength),
Player.
-file("src/rockbox/player.gleam", 1110).
-spec bass_enhancement_decoder() -> gleam@dynamic@decode:decoder(bass_enhancement()).
bass_enhancement_decoder() ->
gleam@dynamic@decode:field(~"strength", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Strength) ->
gleam@dynamic@decode:field(~"precut", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Precut) ->
gleam@dynamic@decode:success({bass_enhancement, Strength, Precut})
end)
end).
-file("src/rockbox/player.gleam", 1095).
-spec crossfeed_decoder() -> gleam@dynamic@decode:decoder(crossfeed()).
crossfeed_decoder() ->
gleam@dynamic@decode:field(~"mode", {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Mode) ->
gleam@dynamic@decode:field(~"direct_gain", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Direct_gain) ->
gleam@dynamic@decode:field(~"cross_gain", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Cross_gain) ->
gleam@dynamic@decode:field(~"high_freq_gain", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(High_freq_gain) ->
gleam@dynamic@decode:field(~"high_freq_cutoff", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(High_freq_cutoff) ->
gleam@dynamic@decode:success({crossfeed, Mode, Direct_gain, Cross_gain, High_freq_gain, High_freq_cutoff})
end)
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 1078).
-spec compressor_decoder() -> gleam@dynamic@decode:decoder(compressor()).
compressor_decoder() ->
gleam@dynamic@decode:field(~"threshold_db", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Threshold_db) ->
gleam@dynamic@decode:field(~"makeup_gain", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Makeup_gain) ->
gleam@dynamic@decode:field(~"ratio", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Ratio) ->
gleam@dynamic@decode:field(~"knee", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Knee) ->
gleam@dynamic@decode:field(~"attack_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Attack_ms) ->
gleam@dynamic@decode:field(~"release_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Release_ms) ->
gleam@dynamic@decode:success({compressor, Threshold_db, Makeup_gain, Ratio, Knee, Attack_ms, Release_ms})
end)
end)
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 1070).
-spec surround_decoder() -> gleam@dynamic@decode:decoder(surround()).
surround_decoder() ->
gleam@dynamic@decode:field(~"delay_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Delay_ms) ->
gleam@dynamic@decode:field(~"balance", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Balance) ->
gleam@dynamic@decode:field(~"cutoff_low_hz", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Cutoff_low_hz) ->
gleam@dynamic@decode:field(~"cutoff_high_hz", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Cutoff_high_hz) ->
gleam@dynamic@decode:success({surround, Delay_ms, Balance, Cutoff_low_hz, Cutoff_high_hz})
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 1062).
-spec tone_decoder() -> gleam@dynamic@decode:decoder(tone()).
tone_decoder() ->
gleam@dynamic@decode:field(~"bass_db", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Bass_db) ->
gleam@dynamic@decode:field(~"treble_db", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Treble_db) ->
gleam@dynamic@decode:field(~"bass_cutoff_hz", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Bass_cutoff_hz) ->
gleam@dynamic@decode:field(~"treble_cutoff_hz", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Treble_cutoff_hz) ->
gleam@dynamic@decode:success({tone, Bass_db, Treble_db, Bass_cutoff_hz, Treble_cutoff_hz})
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 1048).
-spec eq_band_decoder() -> gleam@dynamic@decode:decoder(eq_band()).
eq_band_decoder() ->
gleam@dynamic@decode:field(~"cutoff_hz", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Cutoff_hz) ->
gleam@dynamic@decode:field(~"q", {decoder, fun gleam@dynamic@decode:decode_float/1}, fun(Q) ->
gleam@dynamic@decode:field(~"gain_db", {decoder, fun gleam@dynamic@decode:decode_float/1}, fun(Gain_db) ->
gleam@dynamic@decode:success({eq_band, Cutoff_hz, Q, Gain_db})
end)
end)
end).
-file("src/rockbox/player.gleam", 1055).
-spec equalizer_decoder() -> gleam@dynamic@decode:decoder(equalizer()).
equalizer_decoder() ->
gleam@dynamic@decode:field(~"enabled", {decoder, fun gleam@dynamic@decode:decode_bool/1}, fun(Enabled) ->
gleam@dynamic@decode:field(~"precut_db", {decoder, fun gleam@dynamic@decode:decode_float/1}, fun(Precut_db) ->
gleam@dynamic@decode:field(~"bands", gleam@dynamic@decode:list(eq_band_decoder()), fun(Bands) ->
gleam@dynamic@decode:success({equalizer, Enabled, Precut_db, Bands})
end)
end)
end).
-file("src/rockbox/player.gleam", 1116).
-spec dsp_settings_decoder() -> gleam@dynamic@decode:decoder(dsp_settings()).
dsp_settings_decoder() ->
gleam@dynamic@decode:field(~"equalizer", equalizer_decoder(), fun(Equalizer) ->
gleam@dynamic@decode:field(~"tone", tone_decoder(), fun(Tone) ->
gleam@dynamic@decode:field(~"surround", surround_decoder(), fun(Surround) ->
gleam@dynamic@decode:field(~"channel_mode", {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Channel_mode) ->
gleam@dynamic@decode:field(~"stereo_width", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Stereo_width) ->
gleam@dynamic@decode:field(~"compressor", compressor_decoder(), fun(Compressor) ->
gleam@dynamic@decode:field(~"dither", {decoder, fun gleam@dynamic@decode:decode_bool/1}, fun(Dither) ->
gleam@dynamic@decode:field(~"pitch", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Pitch) ->
gleam@dynamic@decode:field(~"crossfeed", crossfeed_decoder(), fun(Crossfeed) ->
gleam@dynamic@decode:field(~"bass_enhancement", bass_enhancement_decoder(), fun(Bass_enhancement) ->
gleam@dynamic@decode:field(~"fatigue_reduction", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Fatigue_reduction) ->
gleam@dynamic@decode:success({dsp_settings, Equalizer, Tone, Surround, Channel_mode, Stereo_width, Compressor, Dither, Pitch, Crossfeed, Bass_enhancement, Fatigue_reduction})
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end).
-file("src/rockbox/player.gleam", 884).
-spec dsp_settings(player()) -> dsp_settings().
-doc(~" Read back the whole DSP chain state.").
dsp_settings(Player) ->
case gleam@dynamic@decode:run(json:decode(rockbox_ffi_nif:player_dsp_settings_json(Player)), dsp_settings_decoder()) of
{ok, Settings} ->
Settings;
_value ->
erlang:error(#{
gleam_error => let_assert,
message => ~"Pattern match failed, no pattern matched the value.",
file => ~"src/rockbox/player.gleam",
module => ~"rockbox/player",
function => ~"dsp_settings",
line => 885,
value => _value,
start => 22863,
'end' => 22971,
pattern_start => 22874,
pattern_end => 22886
})
end.
-file("src/rockbox/player.gleam", 1000).
-spec resume_decoder() -> gleam@dynamic@decode:decoder(resume_state()).
resume_decoder() ->
gleam@dynamic@decode:field(~"tracks", gleam@dynamic@decode:list({decoder, fun gleam@dynamic@decode:decode_string/1}), fun(Tracks) ->
gleam@dynamic@decode:field(~"index", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Index) ->
gleam@dynamic@decode:field(~"elapsed_ms", {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Elapsed_ms) ->
gleam@dynamic@decode:success({resume_state, Tracks, Index, Elapsed_ms})
end)
end)
end).
-file("src/rockbox/player.gleam", 978).
-spec decode_resume(gleam@dynamic:dynamic_()) -> gleam@option:option(resume_state()).
decode_resume(Value) ->
case gleam@dynamic@decode:run(Value, {decoder, fun gleam@dynamic@decode:decode_string/1}) of
{ok, Json} ->
case gleam@dynamic@decode:run(json:decode(Json), resume_decoder()) of
{ok, State} ->
{some, State};
{error, _} ->
none
end;
{error, _} ->
none
end.
-file("src/rockbox/player.gleam", 894).
-spec resume(player()) -> gleam@option:option(resume_state()).
-doc(~" Restore the queue and exact position from the configured resume file (does
NOT auto-play). `None` if there is nothing to resume.").
resume(Player) ->
decode_resume(rockbox_ffi_nif:player_resume(Player)).
-file("src/rockbox/player.gleam", 899).
-spec save_resume(player()) -> player().
-doc(~" Persist the current queue + position to the resume file right now.").
save_resume(Player) ->
rockbox_ffi_nif:player_save_resume(Player),
Player.
-file("src/rockbox/player.gleam", 908).
-spec clear_resume(player()) -> player().
-doc(~" Delete the resume file (forget the saved state).").
clear_resume(Player) ->
rockbox_ffi_nif:player_clear_resume(Player),
Player.
-file("src/rockbox/player.gleam", 917).
-spec load_resume(binary()) -> gleam@option:option(resume_state()).
-doc(~" Peek at a resume file without a player. `None` if it is missing/unreadable.").
load_resume(Path) ->
case gleam@dynamic@decode:run(rockbox_ffi_nif:load_resume_json(Path), {decoder, fun gleam@dynamic@decode:decode_string/1}) of
{ok, Json} ->
decode_resume(gleam_stdlib:identity(Json));
{error, _} ->
none
end.
-file("src/rockbox/player.gleam", 989).
-spec decode_string_list(gleam@dynamic:dynamic_()) -> list(binary()).
decode_string_list(Value) ->
case gleam@dynamic@decode:run(Value, {decoder, fun gleam@dynamic@decode:decode_string/1}) of
{ok, Json} ->
case gleam@dynamic@decode:run(json:decode(Json), gleam@dynamic@decode:list({decoder, fun gleam@dynamic@decode:decode_string/1})) of
{ok, Paths} ->
Paths;
{error, _} ->
[]
end;
{error, _} ->
[]
end.
-file("src/rockbox/player.gleam", 928).
-spec import_m3u(player(), binary(), insert_position()) -> list(binary()).
-doc(~" Import a playlist file into the queue at `position`; returns the imported
paths.").
import_m3u(Player, Path, Position) ->
{Pos, Index} = insert_position_args(Position),
decode_string_list(rockbox_ffi_nif:player_import_m3u(Player, Path, Pos, Index)).
-file("src/rockbox/player.gleam", 938).
-spec load_m3u(player(), binary()) -> list(binary()).
-doc(~" Replace the queue with a playlist file; returns the loaded paths.").
load_m3u(Player, Path) ->
decode_string_list(rockbox_ffi_nif:player_load_m3u(Player, Path)).
-file("src/rockbox/player.gleam", 943).
-spec export_m3u(player(), binary()) -> {ok, nil} | {error, nil}.
-doc(~" Export the current queue to an `.m3u8` (atomic). `Ok(Nil)` / `Error(Nil)`.").
export_m3u(Player, Path) ->
case rockbox_ffi_nif:player_export_m3u(Player, Path) of
0 ->
{ok, nil};
_ ->
{error, nil}
end.
-file("src/rockbox/player.gleam", 1018).
-spec optional_string() -> gleam@dynamic@decode:decoder(gleam@option:option(binary())).
optional_string() ->
gleam@dynamic@decode:one_of(gleam@dynamic@decode:map({decoder, fun gleam@dynamic@decode:decode_string/1}, fun(_value) ->
{some, _value}
end), [gleam@dynamic@decode:success(none)]).
-file("src/rockbox/player.gleam", 1014).
-spec optional_int() -> gleam@dynamic@decode:decoder(gleam@option:option(integer())).
optional_int() ->
gleam@dynamic@decode:one_of(gleam@dynamic@decode:map({decoder, fun gleam@dynamic@decode:decode_int/1}, fun(_value) ->
{some, _value}
end), [gleam@dynamic@decode:success(none)]).
-file("src/rockbox/player.gleam", 1007).
-spec m3u_entry_decoder() -> gleam@dynamic@decode:decoder(m3u_entry()).
m3u_entry_decoder() ->
gleam@dynamic@decode:field(~"path", {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Path) ->
gleam@dynamic@decode:field(~"duration_ms", optional_int(), fun(Duration_ms) ->
gleam@dynamic@decode:field(~"title", optional_string(), fun(Title) ->
gleam@dynamic@decode:success({m3u_entry, Path, Duration_ms, Title})
end)
end)
end).
-file("src/rockbox/player.gleam", 951).
-spec m3u_read(binary()) -> {ok, list(m3u_entry())} | {error, nil}.
-doc(~" Parse a playlist file into its entries. `Error(Nil)` if it cannot be read.").
m3u_read(Path) ->
case gleam@dynamic@decode:run(rockbox_ffi_nif:m3u_read_json(Path), {decoder, fun gleam@dynamic@decode:decode_string/1}) of
{ok, Json} ->
case gleam@dynamic@decode:run(json:decode(Json), gleam@dynamic@decode:list(m3u_entry_decoder())) of
{ok, Entries} ->
{ok, Entries};
{error, _} ->
{error, nil}
end;
{error, _} ->
{error, nil}
end.
-file("src/rockbox/player.gleam", 963).
-spec m3u_write(binary(), list(binary())) -> {ok, nil} | {error, nil}.
-doc(~" Write a list of paths as an `.m3u8`. `Ok(Nil)` / `Error(Nil)`.").
m3u_write(Path, Paths) ->
case rockbox_ffi_nif:m3u_write_json(Path, erlang:iolist_to_binary(json:encode(Paths))) of
0 ->
{ok, nil};
_ ->
{error, nil}
end.
-file("src/rockbox/player.gleam", 972).
-spec is_url(binary()) -> boolean().
-doc(~" Whether a string looks like an http(s):// URL.").
is_url(S) ->
rockbox_ffi_nif:is_url(S).