Repository navigation
Configuration
The player is configured by a text file on the card and by the Settings page on the panel. The two are one store: what is written on the card is applied at boot, and what is changed on the panel is written back to the card. There is nothing to install and no app; a text editor and the card reader you already use for the music are enough.
A file named evoconfig.txt in the root of the FAT32 card, next to the music. The player reads it on every boot. Without it, the defaults stand: Evo Default, the disc, rotation 0, volume 40.
A ready-made copy with every key and a comment on each is in the repository at sdcard/evoconfig.txt. Copy it to the card and edit the values.
The format:
- One
key = valueper line. Spaces around the=do not matter. - Lines starting with
#or;are comments. There are no comments after a value: everything after the first=is the value. - Wrap a value in
"double quotes"to keep leading or trailing spaces. - An empty value puts the setting back to its default.
- UTF-8, with or without a byte-order mark; LF or CRLF line ends. Any text editor on any system produces a file the player reads.
The keys:
| Key | Values | What it does |
|---|---|---|
theme |
evo-default, night-sky, sunrise, air, liquid
|
The face's theme; see Face. |
style |
disc, card, faders
|
The face's style: art in a ring with the progress round it; art as a rounded square with the text over its foot; or the disc's art with the progress and the volume as faders down the sides in portrait, clear of the transport. See Face. |
rotation |
0, 90, 180, 270
|
Screen rotation, degrees clockwise. 0 and 180 are portrait, 90 and 270 landscape. Applied at boot. |
volume |
0 to 100
|
The level at power-on. |
name |
letters, digits, hyphens; up to 30 | The player's name on the network: the hostname the router is told, so its device list shows it. evo-player when not set. |
wifi_ssid, wifi_password
|
the network's name and password | The Wi-Fi network to join, 2.4 or 5 GHz, WPA2 or WPA3; an empty password means an open network. See below. |
dac |
a board name from Audio out | The DAC board on the header, for a board the player cannot tell by itself (one with no I2C part, such as a PCM5102A) or to override what it found. The player tells an ES9018K2M or a PCM5121/PCM5122 by itself over I2C at boot and brings it up; evostatus.txt lists every address on the header's bus that answered. The key is read and reported; acted on once the register of boards lands. |
output |
speaker, hat, both
|
Where the frames go when the board has a speaker and a DAC both. Read and reported; acted on with dac. |
shuffle |
on, off
|
The order the queue plays in: dealt, or as listed. on when not set. Also an icon on Now Playing and a row of Settings. |
repeat |
all, off, one
|
What happens at the queue's end: it starts again (a fresh deal when shuffled), it stops, or the same track plays again (a track that ends on its own; the next button always moves on). all when not set. Also an icon on Now Playing and a row of Settings. |
start |
a path on the card | What plays at power-on. Not set: the whole card, every file in every folder, in the order above. A folder: that folder, deep. A file: that file, with its folder round it. A playlist (.m3u, .m3u8, .pls): its stations, from the first, or from the one named after a # — start = Radio/Evo Selection.m3u#Classic FM. A station waits for the network to come up ("waiting for the network" on the status strip meanwhile). A path that is not there is reported in evostatus.txt and the card plays. |
snapserver |
host or host:port
|
The Snapcast server to play from; the port is 1704 when left out. Not set: the player looks for one on the network. See Multiroom. |
share, share_user, share_password, share_domain
|
smb://host/share/folder; the account for it |
A network share the library lists under Network: the protocol in the address (smb:// for SMB 2 or later; smb1:// for a box that speaks only SMB1; nfs:// for NFS, 4.1 or 3 as the server speaks), the server by name or address with :port where it is not 445, the share, and a folder within it if wanted. The user and password are SMB's; a guest share needs none, the domain almost never. A second share is share2 with share2_user and so on, up to share9. The password is masked in evostatus.txt. |
web_user, web_password
|
a name and a password | The player's web page (http://<name>.local/, the firmware page) asks for them when both are set; with either empty it is open to everyone on the network. The browser asks once; the password itself never crosses the network (HTTP Digest). Masked in evostatus.txt. |
update |
check, auto, off
|
Newer releases. check (the default): the player looks once a day while on the network and says what it found in Settings and on its page; you install it with two taps on the row or from the page. auto: the same, and it installs by itself once nothing has played for a minute. off: it never looks. See Update. |
update_url |
http:// or https:// address of a manifest |
Where to look for releases instead of the project's own; for a player kept on a release of your choosing. Empty: the project's releases on GitHub. |
A key the player does not know, a value a key cannot take, or a line with no = is ignored and reported; the rest of the file still applies.
The password is on the card in clear, as it is for the Volumio companion's card. The card stays in the player.
With wifi_ssid set, the player joins the network while the music starts; nothing waits for it. A network it has joined before is found again in about three seconds (it remembers the access point's channel and identity); a new one takes a search of both bands, about fourteen seconds. Once joined, the Wi-Fi row of Settings shows the address, the band and the signal, and evostatus.txt gains a line saying the same; while joining the row says so, and if the network cannot be joined it says why. A link that drops is rejoined.
Prefer 5 GHz where the network offers it. The player takes whichever band the access point gives it, and on 2.4 GHz the status strip says so (2.4 GHz Wi-Fi, between the source and the stream), as it says weak Wi-Fi when the signal is poor on either band. Measured on the bench against the same access point: a round trip of 3 to 9 ms on 5 GHz, 25 to 125 ms on 2.4 GHz; a Snapcast stream played clean on both, but on 2.4 GHz its clock wandered by a few milliseconds where on 5 GHz it held to a fraction of one, so rooms sit less exactly together. The player's radio does not take part in the choice of band beyond the search; a network that puts the player on 2.4 GHz can be given a 5 GHz-only name for it.
The network carries internet radio (below), and the player announces itself on it as an Evo device so a multiroom group can send to it (Multiroom). The Evo id row at the bottom of Settings is the id a group adds.
Joining a network, like anything else that keeps the chip busy for a moment, does not reach the ear: the player decodes up to 600 ms ahead into a reservoir, and a task above everything else carries the audio to the DAC. A pause takes effect within about 70 ms and resumes exactly where it stopped; a seek is immediate; a track started afresh begins after a short gathering pause of a quarter second, and a track that follows another plays on without a gap.
Stations come from playlists on the card. A .m3u, .m3u8 or .pls file in any folder lists them; the playlist is a folder of its own in the library (Radio › Evo Selection › …), its stations in the playlist's order, and a tap plays one once the network is up. The queue is then that playlist: the next button moves to the next station (shuffle and repeat apply as set). To come up on a station at power-on, name it in start (above). The card image in the repository carries Radio/Evo Selection.m3u, a checked selection of UK stations (and Radio Paradise's FLAC streams) drawn from the open radio-browser.info directory. Edit it, or add your own files beside it:
#EXTM3U
#EXTINF:-1 tvg-logo="https://www.classicfm.com/assets_v4r/classic/img/favicon-196x196.png",Classic FM
http://media-ice.musicradio.com/ClassicFMMP3
#EXTINF:-1 tvg-logo="logos/mine.png",My Station
http://host.example/stream
Each #EXTINF line names the station on the URL line below it; a station without one is named by its host. tvg-logo (the attribute IPTV lists use) is the station's picture: a URL, or a path on the card relative to the playlist's folder; PNG (with transparency, which is composed onto the theme's background) or JPEG. A logo is set whole on a square of the background, since its width is its shape, where a cover is cropped to its centre. A station without a logo shows its name in the art square instead. .pls files take FileN= and TitleN= pairs and have no logo.
While a station plays, its name is the album line; where the server sends what is playing (Icecast and SHOUTcast metadata), the title and artist follow the songs. A line too long for its width ends in an ellipsis; a tap on the text raises the details sheet, a card over the middle of the face with the whole title, artist, station and format, and a tap anywhere puts it down (the navigation works through it; a track change puts it down by itself). Nothing on the face moves on its own. Stations have no end and no seek, and the boot's run through the card leaves them out.
What plays from the air: MP3, AAC (AAC-LC and HE-AAC, through Espressif's decoder), FLAC and Ogg Vorbis, http:// and https:// (redirects followed), as one long stream or as HLS — a playlist of short MPEG-TS segments, the way the BBC broadcasts: the player follows a master playlist to the audio variant nearest 160 kb/s from below, starts three segments behind the live edge, fetches each segment in turn and hands the audio inside to the decoder as if it were one stream. Segments in fragmented MP4 are not played; the status strip says so. An AAC-LC station costs about a third of the core, an MP3 station a fifth, an HE-AAC station (the BBC's international feeds, 96 kb/s with SBR to 48 kHz) about three quarters — it plays in real time with a tenth of the core to spare, and nothing else on the player is slowed, but it is the heaviest thing the board does; the shipped list prefers a broadcaster's MP3 feed where it offers both. The decoders' working memory lives in PSRAM beyond what the drivers can spare of internal SRAM (about 40 KB stays free with any station open). The BBC's national stations are in the shipped list by their stable manifests (a.files.bbci.co.uk), on the international 96 kb/s HE-AAC feeds that play anywhere; a listener in the UK can change nonuk to uk and low_sbr to high_sbr in a BBC address for the 320 kb/s AAC-LC feed.
A station that will not open stays on the face with the reason on the status strip — "Jazz24: not found (404)", "Absolut Relax: could not connect", "Radio 4: HLS in fragmented MP4 is not played" — rather than the player moving on to another station unasked; a file that will not open is passed over, as before. A connection that drops while a station plays is opened again, three times with a lengthening pause, and the music resumes where the stream is; a station that ends for good holds with "the stream ended", and Play tries it again. The stream is fetched by a thread of its own into a 512 KB ring in PSRAM, a second and a half ahead before the first note, so the decoder never waits on the network. Expect the heartbeat's internal figure to be around 20 KB lower while a station plays.
The library's first page lists its sources: Card and Network. Network lists the media servers on the local network — anything that speaks DLNA (UPnP AV): a NAS's built-in server, MiniDLNA, Plex, a Sonos system, Volumio's own — and the shares named in evoconfig.txt, each as the tree of folders the server presents (Music › Artist › …, or Browse Folders for the shares as they are). A tap on a track plays it, and the folder becomes the queue from there, as on the card. The player searches for servers from the moment it joins the network and again every minute; a server that answers after the page was opened appears within a couple of seconds, and a server switched off disappears at the next search.
A server's track is a file, not a station: it has a length, the progress ring and the strip show the time, a lift on the ring or a drag on the strip seeks (the player asks the server for the file from that point, which a DLNA server does without a second thought), shuffle and repeat apply, and the boot's run through the card leaves network tracks out as it does stations. The title, artist, album, length and the cover come from the server's listing, so a track shows them before the first byte arrives. What plays is what the card plays — FLAC, WAV, MP3, AAC, Ogg Vorbis — within the same rate ceiling (see Hardware); the server sends the file as it is, nothing is transcoded.
Shares. A share named in evoconfig.txt (share = smb://nas.local/Music, with share_user and share_password where the server wants an account) is listed under Network beside the servers found, as Music on nas.local, and below it the share's own folders and audio files. The player speaks SMB 2.0.2, 2.1 and 3.1.1 — every NAS, Windows and Samba of the last fifteen years, signed when the server requires it (Windows 11 does) and encrypted when the server or the share requires that (a NAS's "encrypt data" switch, Samba's smb encrypt = required); an encrypted share needs an account, since a guest session has no key to encrypt with — and never SMB1 on an smb:// share, so an old box cannot pull it down to the insecure protocol. Encryption costs the chip some effort: a 44.1 or 48 kHz track from an encrypted share plays as any other; a 96 kHz FLAC from one plays, with little to spare, and a 96 kHz library is better served from a share without encryption or from NFS. For a box that speaks only SMB1 — a NAS or a router's USB share from the 2000s — write the share as smb1://oldbox/music: that share, and only that share, is spoken in the old dialect, with the same user and password keys. An smb:// share whose server answers nothing to SMB2 is reported in the log as an SMB1-only box so the address can be changed. An NFS export is share = nfs://nas.local/volume1/music — the export and, if wanted, a folder below it; no user or password (the player presents itself as an ordinary user, uid 1000, and a NAS that squashes everyone to a guest is fine). NFS 4.1 where the server speaks it (one connection, no portmapper), version 3 where it does not, over TCP; an export marked secure, the default on most servers, is reached, since the player connects from a reserved port as a computer would. The server's NFS rule must allow the player's address. Each file's rate and length are read from its header when the folder is listed, so a 192 kHz file on a share is greyed as one on the card is. A file is read by position, so a seek costs nothing but the next read; the player opens one session per track and lets it go when the track ends. A share that cannot be reached, a wrong password or a share name the server does not know each give their reason in the log rather than an empty page.
The same goes for a file on an ordinary web server, reached from a playlist on the card: an entry whose #EXTINF carries a length (#EXTINF:243,My track — a station's is -1) is read as a file with that duration and gets the ring, seek and the queue's modes; an entry without one is a station. The file's first 64 KB and last 4 KB are kept so the decoder's look at the end costs one short request; a seek costs one, plus, on a FLAC with no seek table, the decoder's few probes around the point (a rip from a CD has a seek table, a file from ffmpeg has none).
On every boot the player writes evostatus.txt next to evoconfig.txt, so a card taken back to a computer says what the player did with the file. It carries the player's version and build, what is running (theme, style, rotation, volume, how many tracks the card has), one read: line per setting the file supplied (the password shown only by its length), one line per setting that was read but not acted on by this firmware, and one line, with its line number, per entry that was ignored and why. A card with no evoconfig.txt gets a status file saying so and that the defaults apply.
The third item of the navigation (the bar along the foot in portrait, the rail on the left in landscape) is Settings: the player's facts, one a row. Rows marked with › are settings; a tap changes them, on the panel and in the file:
- Update › says where the player stands with releases: up to date, 0.2.0 available, waiting for a quiet moment, check failed: …, or off. With a release available, two taps within twelve seconds install it; see Update.
- Theme › steps through the five themes. The face repaints in the new one.
- Style › steps through disc, card and faders. The face repaints, and the album's picture is fetched again at the new size.
- Rotation › turns a quarter clockwise. The panel is oriented when the player starts, so this writes the setting and restarts the player, which comes up turned: the panel lights again about five seconds after the tap, saying "Reading the card…" until the music resumes a second later. During a new firmware's trial minute the restart waits until the firmware has confirmed itself (the panel says so), since a restart before that would return the player to the firmware it had.
- Shuffle › turns the shuffle on or off. On, the tracks not yet played are dealt afresh; off, the queue goes on in the listed order from the track in hand. What is playing is not interrupted.
- Repeat › steps through all, one and off.
The other rows are facts: the player and its build, the network's address, the board, and the card's size and track count. The list is longer than the page; a drag scrolls it.
Changing a setting on the panel rewrites that one line of evoconfig.txt in place. Every other line, comment and blank stays as it was written. A card with no evoconfig.txt gets one with the changed key the first time a setting is tapped.
Now Playing takes touch. Where the controls are depends on the style:
| Disc | Card | |
|---|---|---|
| Play/pause, previous, next | The three buttons under the text. Next and previous move through the queue in its order (shuffled or listed); after the queue's end, Play starts it again; on a held station, Play tries it again. | The same. |
| Shuffle, repeat | The two flat icons outside previous and next (portrait), or on the row under the transport (landscape): lit in the accent when on; repeat shows a 1 for repeat-one. One tap toggles shuffle, one tap steps repeat through all, one and off; the file on the card is updated. They apply to files and are not shown while a station plays. |
The same. |
| Seek | Touch the ring around the art and lift where the track should go. | The strip with the times at its ends; drag along it. |
| Volume | The strip under the text in portrait, under the art in landscape; drag along it. | Its own row: under the seek strip in portrait, above it in landscape; drag along it. |
| Library | The second item of the navigation: the sources — Card and Network (the media servers found on the network) — and their folders and tracks. A tap on a folder opens it, on a track plays it and makes its folder the queue from there; the chevron at the head goes up a folder; a drag scrolls. A greyed row is a track above the board's rate ceiling (see Hardware) or an AAC station. | The same. |
The volume slider's and the seek strip's touch reaches extend a few pixels above and below the bar; on the landscape card, where the two rows are close, the nearer bar takes the finger.
evo-esp32 is designed, built and maintained by one developer in his own time. If it has earned a place on your bench:
Provided as-is under the Business Source License 1.1; sponsorship is a thank-you, not a purchase: it buys no priority, no features and no support agreement. evo™ and evoframework™ are trademarks of Just a Nerd.