Current section
Files
Jump to
Current section
Files
src/rockbox@player.erl
-module(rockbox@player).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/rockbox/player.gleam").
-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, 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]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Queue-based player with native ReplayGain and Rockbox crossfade.\n"
"\n"
" A `Player` owns a live audio output device and a background engine\n"
" thread, so it only works where an output device exists. The handle is a\n"
" NIF resource, freed by the BEAM garbage collector (which stops playback).\n"
"\n"
" ReplayGain `mode` here uses the player values: 0 off, 1 track, 2 album.\n"
" Crossfade `mode`: 0 off, 1 auto-skip, 2 manual-skip, 3 shuffle,\n"
" 4 shuffle-or-manual, 5 always. Mix mode: 0 crossfade, 1 mix.\n"
"\n"
" Mutating functions return the `Player`, so they can be piped:\n"
"\n"
" p\n"
" |> player.set_queue(tracks)\n"
" |> player.set_shuffle(True)\n"
" |> player.set_repeat(player.All)\n"
" |> player.play\n"
).
-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()}.
-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", 83).
?DOC(
" Rockbox-default configuration (device sample rate, no crossfade,\n"
" ReplayGain off, full volume, resume disabled).\n"
).
-spec default_config() -> config().
default_config() ->
{config, 0, 4.0, 1.0, 0, +0.0, true, 0, 0, 2000, 0, 2000, 0, none, 0}.
-file("src/rockbox/player.gleam", 104).
?DOC(
" Encode an `InsertPosition` as the ABI's integer tag plus the index arg\n"
" (only meaningful for `Index`).\n"
).
-spec insert_position_args(insert_position()) -> {integer(), integer()}.
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", 144).
?DOC(" Encode an `EqPreset` as the ABI's integer id (0..20).\n").
-spec eq_preset_to_int(eq_preset()) -> integer().
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", 183).
?DOC(" Encode a `ChannelMode` as the ABI's integer id (0..6).\n").
-spec channel_mode_to_int(channel_mode()) -> integer().
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", 204).
?DOC(" Encode a `CrossfeedMode` as the ABI's integer id (0/1/2).\n").
-spec crossfeed_mode_to_int(crossfeed_mode()) -> integer().
crossfeed_mode_to_int(Mode) ->
case Mode of
crossfeed_off ->
0;
meier ->
1;
crossfeed_custom ->
2
end.
-file("src/rockbox/player.gleam", 221).
?DOC(" Encode a `RepeatMode` as the ABI's integer id (0/1/2).\n").
-spec repeat_mode_to_int(repeat_mode()) -> integer().
repeat_mode_to_int(Mode) ->
case Mode of
off ->
0;
one ->
1;
all ->
2
end.
-file("src/rockbox/player.gleam", 230).
?DOC(" Decode the ABI's integer id (0/1/2) into a `RepeatMode` (unknown → `Off`).\n").
-spec repeat_mode_from_int(integer()) -> repeat_mode().
repeat_mode_from_int(Value) ->
case Value of
1 ->
one;
2 ->
all;
_ ->
off
end.
-file("src/rockbox/player.gleam", 328).
?DOC(" Create a player on the default device with default settings.\n").
-spec new() -> player().
new() ->
rockbox_ffi_nif:player_new().
-file("src/rockbox/player.gleam", 331).
?DOC(" Create a player with explicit configuration (including resume).\n").
-spec with_config(config()) -> player().
with_config(C) ->
Resume_file = case erlang:element(14, C) of
{some, Path} ->
gleam_stdlib:identity(Path);
none ->
gleam@dynamic:nil()
end,
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)
).
-file("src/rockbox/player.gleam", 358).
?DOC(
" Replace the queue. Each entry may be a local file path, an `http(s)://`\n"
" URL to a finite remote file, or a live-radio / streaming URL.\n"
).
-spec set_queue(player(), list(binary())) -> player().
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", 364).
?DOC(" Insert a list of paths / URLs into the queue at `position`.\n").
-spec insert(player(), list(binary()), insert_position()) -> player().
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", 375).
?DOC(" The current queue as a list of paths / URLs.\n").
-spec queue(player()) -> list(binary()).
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", 384).
?DOC(
" Append one track to the queue. `path` may be a local file path, an\n"
" `http(s)://` URL to a finite remote file, or a live-radio / streaming URL.\n"
).
-spec enqueue(player(), binary()) -> player().
enqueue(Player, Path) ->
rockbox_ffi_nif:player_enqueue(Player, Path),
Player.
-file("src/rockbox/player.gleam", 393).
?DOC(" Start (or resume) playback.\n").
-spec play(player()) -> player().
play(Player) ->
rockbox_ffi_nif:player_play(Player),
Player.
-file("src/rockbox/player.gleam", 402).
?DOC(" Pause playback.\n").
-spec pause(player()) -> player().
pause(Player) ->
rockbox_ffi_nif:player_pause(Player),
Player.
-file("src/rockbox/player.gleam", 411).
?DOC(" Toggle between play and pause.\n").
-spec toggle(player()) -> player().
toggle(Player) ->
rockbox_ffi_nif:player_toggle(Player),
Player.
-file("src/rockbox/player.gleam", 420).
?DOC(" Stop playback.\n").
-spec stop(player()) -> player().
stop(Player) ->
rockbox_ffi_nif:player_stop(Player),
Player.
-file("src/rockbox/player.gleam", 429).
?DOC(" Skip to the next track.\n").
-spec next(player()) -> player().
next(Player) ->
rockbox_ffi_nif:player_next(Player),
Player.
-file("src/rockbox/player.gleam", 438).
?DOC(" Skip to the previous track.\n").
-spec previous(player()) -> player().
previous(Player) ->
rockbox_ffi_nif:player_previous(Player),
Player.
-file("src/rockbox/player.gleam", 447).
?DOC(" Skip to the track at `index` in the queue.\n").
-spec skip_to(player(), integer()) -> player().
skip_to(Player, Index) ->
rockbox_ffi_nif:player_skip_to(Player, Index),
Player.
-file("src/rockbox/player.gleam", 456).
?DOC(" Seek to `ms` within the current track.\n").
-spec seek_ms(player(), integer()) -> player().
seek_ms(Player, Ms) ->
rockbox_ffi_nif:player_seek_ms(Player, Ms),
Player.
-file("src/rockbox/player.gleam", 465).
?DOC(" Set the output volume (0.0..1.0).\n").
-spec set_volume(player(), float()) -> player().
set_volume(Player, Volume) ->
rockbox_ffi_nif:player_set_volume(Player, Volume),
Player.
-file("src/rockbox/player.gleam", 474).
?DOC(" Set the stereo balance, -100 (full left) to +100 (full right); 0 = centre.\n").
-spec set_balance(player(), integer()) -> player().
set_balance(Player, Balance) ->
rockbox_ffi_nif:player_set_balance(Player, Balance),
Player.
-file("src/rockbox/player.gleam", 483).
-spec volume(player()) -> float().
volume(Player) ->
rockbox_ffi_nif:player_volume(Player).
-file("src/rockbox/player.gleam", 487).
?DOC(" Current stereo balance, -100 (full left) to +100 (full right).\n").
-spec balance(player()) -> integer().
balance(Player) ->
rockbox_ffi_nif:player_balance(Player).
-file("src/rockbox/player.gleam", 490).
-spec sample_rate(player()) -> integer().
sample_rate(Player) ->
rockbox_ffi_nif:player_sample_rate(Player).
-file("src/rockbox/player.gleam", 493).
?DOC(" Configure crossfade behaviour.\n").
-spec set_crossfade(
player(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()
) -> player().
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", 526).
?DOC(" Configure ReplayGain (mode, pre-amp in dB, clipping prevention).\n").
-spec set_replaygain(player(), integer(), float(), boolean()) -> player().
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", 967).
-spec status_decoder() -> gleam@dynamic@decode:decoder(status()).
status_decoder() ->
gleam@dynamic@decode:field(
<<"state"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(State) ->
gleam@dynamic@decode:field(
<<"index"/utf8>>,
gleam@dynamic@decode:one_of(
gleam@dynamic@decode:map(
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Field@0) -> {some, Field@0} end
),
[gleam@dynamic@decode:success(none)]
),
fun(Index) ->
gleam@dynamic@decode:field(
<<"position_ms"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Position_ms) ->
gleam@dynamic@decode:field(
<<"duration_ms"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Duration_ms) ->
gleam@dynamic@decode:field(
<<"queue_len"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_int/1},
fun(Queue_len) ->
gleam@dynamic@decode:field(
<<"shuffle"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_bool/1},
fun(Shuffle) ->
gleam@dynamic@decode:field(
<<"repeat"/utf8>>,
{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", 545).
?DOC(" A snapshot of the player's status.\n").
-spec status(player()) -> status().
status(Player) ->
Status@1 = case gleam@dynamic@decode:run(
json:decode(rockbox_ffi_nif:player_status_json(Player)),
status_decoder()
) of
{ok, Status} -> Status;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rockbox/player"/utf8>>,
function => <<"status"/utf8>>,
line => 546,
value => _assert_fail,
start => 13297,
'end' => 13391,
pattern_start => 13308,
pattern_end => 13318})
end,
Status@1.
-file("src/rockbox/player.gleam", 554).
?DOC(" Enable or disable shuffle playback.\n").
-spec set_shuffle(player(), boolean()) -> player().
set_shuffle(Player, Enabled) ->
rockbox_ffi_nif:player_set_shuffle(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 564).
?DOC(" Whether shuffle playback is currently enabled.\n").
-spec is_shuffle_enabled(player()) -> boolean().
is_shuffle_enabled(Player) ->
rockbox_ffi_nif:player_is_shuffle_enabled(Player).
-file("src/rockbox/player.gleam", 567).
?DOC(" Set the repeat mode (off / one / all).\n").
-spec set_repeat(player(), repeat_mode()) -> player().
set_repeat(Player, Mode) ->
rockbox_ffi_nif:player_set_repeat(Player, repeat_mode_to_int(Mode)),
Player.
-file("src/rockbox/player.gleam", 573).
?DOC(" The current repeat mode (off / one / all).\n").
-spec repeat(player()) -> repeat_mode().
repeat(Player) ->
repeat_mode_from_int(rockbox_ffi_nif:player_repeat(Player)).
-file("src/rockbox/player.gleam", 580).
?DOC(" Enable or disable the graphic equalizer.\n").
-spec set_eq_enabled(player(), boolean()) -> player().
set_eq_enabled(Player, Enabled) ->
rockbox_ffi_nif:player_set_eq_enabled(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 590).
?DOC(" Whether the graphic equalizer is currently enabled.\n").
-spec is_eq_enabled(player()) -> boolean().
is_eq_enabled(Player) ->
rockbox_ffi_nif:player_is_eq_enabled(Player).
-file("src/rockbox/player.gleam", 593).
?DOC(" Configure one EQ band: `cutoff_hz` in Hz, `q` factor, `gain_db` in dB.\n").
-spec set_eq_band(player(), integer(), integer(), float(), float()) -> player().
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", 614).
?DOC(" Set the EQ pre-cut (headroom), in dB.\n").
-spec set_eq_precut(player(), float()) -> player().
set_eq_precut(Player, Db) ->
rockbox_ffi_nif:player_set_eq_precut(Player, Db),
Player.
-file("src/rockbox/player.gleam", 623).
?DOC(" Apply a built-in EQ preset.\n").
-spec set_eq_preset(player(), eq_preset()) -> player().
set_eq_preset(Player, Preset) ->
rockbox_ffi_nif:player_set_eq_preset(Player, eq_preset_to_int(Preset)),
Player.
-file("src/rockbox/player.gleam", 629).
?DOC(" Set the bass/treble tone controls (gains in dB, cutoffs in Hz).\n").
-spec set_tone(player(), integer(), integer(), integer(), integer()) -> player().
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", 650).
?DOC(" Set the bass tone gain, in dB.\n").
-spec set_bass(player(), integer()) -> player().
set_bass(Player, Bass_db) ->
rockbox_ffi_nif:player_set_bass(Player, Bass_db),
Player.
-file("src/rockbox/player.gleam", 659).
?DOC(" Set the treble tone gain, in dB.\n").
-spec set_treble(player(), integer()) -> player().
set_treble(Player, Treble_db) ->
rockbox_ffi_nif:player_set_treble(Player, Treble_db),
Player.
-file("src/rockbox/player.gleam", 668).
?DOC(" Configure the surround effect (delay in ms, balance, cutoffs in Hz).\n").
-spec set_surround(player(), integer(), integer(), integer(), integer()) -> player().
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", 689).
?DOC(" Set the channel-mixing mode.\n").
-spec set_channel_mode(player(), channel_mode()) -> player().
set_channel_mode(Player, Mode) ->
rockbox_ffi_nif:player_set_channel_mode(Player, channel_mode_to_int(Mode)),
Player.
-file("src/rockbox/player.gleam", 695).
?DOC(" Set the stereo width, as a percentage.\n").
-spec set_stereo_width(player(), integer()) -> player().
set_stereo_width(Player, Percent) ->
rockbox_ffi_nif:player_set_stereo_width(Player, Percent),
Player.
-file("src/rockbox/player.gleam", 704).
?DOC(" Configure the dynamic-range compressor.\n").
-spec set_compressor(
player(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()
) -> player().
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", 737).
?DOC(" Enable or disable output dithering.\n").
-spec set_dither(player(), boolean()) -> player().
set_dither(Player, Enabled) ->
rockbox_ffi_nif:player_set_dither(Player, Enabled),
Player.
-file("src/rockbox/player.gleam", 746).
?DOC(" Set the pitch ratio (Rockbox's fixed-point pitch value).\n").
-spec set_pitch(player(), integer()) -> player().
set_pitch(Player, Ratio) ->
rockbox_ffi_nif:player_set_pitch(Player, Ratio),
Player.
-file("src/rockbox/player.gleam", 755).
?DOC(" Set the bass tone cutoff frequency, in Hz.\n").
-spec set_bass_cutoff(player(), integer()) -> player().
set_bass_cutoff(Player, Hz) ->
rockbox_ffi_nif:player_set_bass_cutoff(Player, Hz),
Player.
-file("src/rockbox/player.gleam", 764).
?DOC(" Set the treble tone cutoff frequency, in Hz.\n").
-spec set_treble_cutoff(player(), integer()) -> player().
set_treble_cutoff(Player, Hz) ->
rockbox_ffi_nif:player_set_treble_cutoff(Player, Hz),
Player.
-file("src/rockbox/player.gleam", 775).
?DOC(
" Configure the crossfeed (headphone) effect. `direct_gain`, `cross_gain`\n"
" and `high_freq_gain` are gains; `high_freq_cutoff` is in Hz. The gain\n"
" values only take effect in `CrossfeedCustom` mode.\n"
).
-spec set_crossfeed(
player(),
crossfeed_mode(),
integer(),
integer(),
integer(),
integer()
) -> player().
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", 805).
?DOC(" Configure bass enhancement (`strength` and `precut`).\n").
-spec set_bass_enhancement(player(), integer(), integer()) -> player().
set_bass_enhancement(Player, Strength, Precut) ->
rockbox_ffi_nif:player_set_bass_enhancement(Player, Strength, Precut),
Player.
-file("src/rockbox/player.gleam", 818).
?DOC(" Set the listening-fatigue reduction strength.\n").
-spec set_fatigue_reduction(player(), integer()) -> player().
set_fatigue_reduction(Player, Strength) ->
rockbox_ffi_nif:player_set_fatigue_reduction(Player, Strength),
Player.
-file("src/rockbox/player.gleam", 1053).
-spec bass_enhancement_decoder() -> gleam@dynamic@decode:decoder(bass_enhancement()).
bass_enhancement_decoder() ->
gleam@dynamic@decode:field(
<<"strength"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Strength) ->
gleam@dynamic@decode:field(
<<"precut"/utf8>>,
{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", 1038).
-spec crossfeed_decoder() -> gleam@dynamic@decode:decoder(crossfeed()).
crossfeed_decoder() ->
gleam@dynamic@decode:field(
<<"mode"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Mode) ->
gleam@dynamic@decode:field(
<<"direct_gain"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Direct_gain) ->
gleam@dynamic@decode:field(
<<"cross_gain"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Cross_gain) ->
gleam@dynamic@decode:field(
<<"high_freq_gain"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(High_freq_gain) ->
gleam@dynamic@decode:field(
<<"high_freq_cutoff"/utf8>>,
{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", 1021).
-spec compressor_decoder() -> gleam@dynamic@decode:decoder(compressor()).
compressor_decoder() ->
gleam@dynamic@decode:field(
<<"threshold_db"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Threshold_db) ->
gleam@dynamic@decode:field(
<<"makeup_gain"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Makeup_gain) ->
gleam@dynamic@decode:field(
<<"ratio"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Ratio) ->
gleam@dynamic@decode:field(
<<"knee"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Knee) ->
gleam@dynamic@decode:field(
<<"attack_ms"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_int/1},
fun(Attack_ms) ->
gleam@dynamic@decode:field(
<<"release_ms"/utf8>>,
{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", 1013).
-spec surround_decoder() -> gleam@dynamic@decode:decoder(surround()).
surround_decoder() ->
gleam@dynamic@decode:field(
<<"delay_ms"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Delay_ms) ->
gleam@dynamic@decode:field(
<<"balance"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Balance) ->
gleam@dynamic@decode:field(
<<"cutoff_low_hz"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Cutoff_low_hz) ->
gleam@dynamic@decode:field(
<<"cutoff_high_hz"/utf8>>,
{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", 1005).
-spec tone_decoder() -> gleam@dynamic@decode:decoder(tone()).
tone_decoder() ->
gleam@dynamic@decode:field(
<<"bass_db"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Bass_db) ->
gleam@dynamic@decode:field(
<<"treble_db"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Treble_db) ->
gleam@dynamic@decode:field(
<<"bass_cutoff_hz"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Bass_cutoff_hz) ->
gleam@dynamic@decode:field(
<<"treble_cutoff_hz"/utf8>>,
{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", 991).
-spec eq_band_decoder() -> gleam@dynamic@decode:decoder(eq_band()).
eq_band_decoder() ->
gleam@dynamic@decode:field(
<<"cutoff_hz"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Cutoff_hz) ->
gleam@dynamic@decode:field(
<<"q"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_float/1},
fun(Q) ->
gleam@dynamic@decode:field(
<<"gain_db"/utf8>>,
{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", 998).
-spec equalizer_decoder() -> gleam@dynamic@decode:decoder(equalizer()).
equalizer_decoder() ->
gleam@dynamic@decode:field(
<<"enabled"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_bool/1},
fun(Enabled) ->
gleam@dynamic@decode:field(
<<"precut_db"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_float/1},
fun(Precut_db) ->
gleam@dynamic@decode:field(
<<"bands"/utf8>>,
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", 1059).
-spec dsp_settings_decoder() -> gleam@dynamic@decode:decoder(dsp_settings()).
dsp_settings_decoder() ->
gleam@dynamic@decode:field(
<<"equalizer"/utf8>>,
equalizer_decoder(),
fun(Equalizer) ->
gleam@dynamic@decode:field(
<<"tone"/utf8>>,
tone_decoder(),
fun(Tone) ->
gleam@dynamic@decode:field(
<<"surround"/utf8>>,
surround_decoder(),
fun(Surround) ->
gleam@dynamic@decode:field(
<<"channel_mode"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Channel_mode) ->
gleam@dynamic@decode:field(
<<"stereo_width"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_int/1},
fun(Stereo_width) ->
gleam@dynamic@decode:field(
<<"compressor"/utf8>>,
compressor_decoder(),
fun(Compressor) ->
gleam@dynamic@decode:field(
<<"dither"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_bool/1},
fun(Dither) ->
gleam@dynamic@decode:field(
<<"pitch"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_int/1},
fun(Pitch) ->
gleam@dynamic@decode:field(
<<"crossfeed"/utf8>>,
crossfeed_decoder(
),
fun(
Crossfeed
) ->
gleam@dynamic@decode:field(
<<"bass_enhancement"/utf8>>,
bass_enhancement_decoder(
),
fun(
Bass_enhancement
) ->
gleam@dynamic@decode:field(
<<"fatigue_reduction"/utf8>>,
{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", 827).
?DOC(" Read back the whole DSP chain state.\n").
-spec dsp_settings(player()) -> dsp_settings().
dsp_settings(Player) ->
Settings@1 = case gleam@dynamic@decode:run(
json:decode(rockbox_ffi_nif:player_dsp_settings_json(Player)),
dsp_settings_decoder()
) of
{ok, Settings} -> Settings;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rockbox/player"/utf8>>,
function => <<"dsp_settings"/utf8>>,
line => 828,
value => _assert_fail,
start => 20678,
'end' => 20786,
pattern_start => 20689,
pattern_end => 20701})
end,
Settings@1.
-file("src/rockbox/player.gleam", 943).
-spec resume_decoder() -> gleam@dynamic@decode:decoder(resume_state()).
resume_decoder() ->
gleam@dynamic@decode:field(
<<"tracks"/utf8>>,
gleam@dynamic@decode:list(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Tracks) ->
gleam@dynamic@decode:field(
<<"index"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Index) ->
gleam@dynamic@decode:field(
<<"elapsed_ms"/utf8>>,
{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", 921).
-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", 837).
?DOC(
" Restore the queue and exact position from the configured resume file (does\n"
" NOT auto-play). `None` if there is nothing to resume.\n"
).
-spec resume(player()) -> gleam@option:option(resume_state()).
resume(Player) ->
decode_resume(rockbox_ffi_nif:player_resume(Player)).
-file("src/rockbox/player.gleam", 842).
?DOC(" Persist the current queue + position to the resume file right now.\n").
-spec save_resume(player()) -> player().
save_resume(Player) ->
rockbox_ffi_nif:player_save_resume(Player),
Player.
-file("src/rockbox/player.gleam", 851).
?DOC(" Delete the resume file (forget the saved state).\n").
-spec clear_resume(player()) -> player().
clear_resume(Player) ->
rockbox_ffi_nif:player_clear_resume(Player),
Player.
-file("src/rockbox/player.gleam", 860).
?DOC(" Peek at a resume file without a player. `None` if it is missing/unreadable.\n").
-spec load_resume(binary()) -> gleam@option:option(resume_state()).
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", 932).
-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", 871).
?DOC(
" Import a playlist file into the queue at `position`; returns the imported\n"
" paths.\n"
).
-spec import_m3u(player(), binary(), insert_position()) -> list(binary()).
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", 881).
?DOC(" Replace the queue with a playlist file; returns the loaded paths.\n").
-spec load_m3u(player(), binary()) -> list(binary()).
load_m3u(Player, Path) ->
decode_string_list(rockbox_ffi_nif:player_load_m3u(Player, Path)).
-file("src/rockbox/player.gleam", 886).
?DOC(" Export the current queue to an `.m3u8` (atomic). `Ok(Nil)` / `Error(Nil)`.\n").
-spec export_m3u(player(), binary()) -> {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", 961).
-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(Field@0) -> {some, Field@0} end
),
[gleam@dynamic@decode:success(none)]
).
-file("src/rockbox/player.gleam", 957).
-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(Field@0) -> {some, Field@0} end
),
[gleam@dynamic@decode:success(none)]
).
-file("src/rockbox/player.gleam", 950).
-spec m3u_entry_decoder() -> gleam@dynamic@decode:decoder(m3u_entry()).
m3u_entry_decoder() ->
gleam@dynamic@decode:field(
<<"path"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Path) ->
gleam@dynamic@decode:field(
<<"duration_ms"/utf8>>,
optional_int(),
fun(Duration_ms) ->
gleam@dynamic@decode:field(
<<"title"/utf8>>,
optional_string(),
fun(Title) ->
gleam@dynamic@decode:success(
{m3u_entry, Path, Duration_ms, Title}
)
end
)
end
)
end
).
-file("src/rockbox/player.gleam", 894).
?DOC(" Parse a playlist file into its entries. `Error(Nil)` if it cannot be read.\n").
-spec m3u_read(binary()) -> {ok, list(m3u_entry())} | {error, nil}.
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", 906).
?DOC(" Write a list of paths as an `.m3u8`. `Ok(Nil)` / `Error(Nil)`.\n").
-spec m3u_write(binary(), list(binary())) -> {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", 915).
?DOC(" Whether a string looks like an http(s):// URL.\n").
-spec is_url(binary()) -> boolean().
is_url(S) ->
rockbox_ffi_nif:is_url(S).