The SD Library
Safi builds its library by scanning the SD card at boot and whenever the card is re-inserted. Get the layout right and everything else (browse mode, the dashboard library, NFC cards, favorites) works from it.
Card requirements
- microSD, formatted FAT32. Cards up to 32 GB format as FAT32 out of the box; larger cards work but must be explicitly formatted FAT32 (exFAT is not supported).
- Any speed class is fine: audio playback reads about 20 KB/s, orders of magnitude below even the slowest cards.
Folder layout
One folder per reciter at the card root; audio files inside named by surah number:
/
├── Al-Husary/
│ ├── 001.mp3
│ ├── 002.mp3
│ └── ... up to 114.mp3
├── Al-Minshawi/
│ ├── 001_Al-Fatihah.mp3
│ └── ...
└── Abdul-Basit/
└── ...
The rules the scanner applies:
- The first three characters of the filename must be the surah number, 001 through 114. Everything after the digits is ignored, so
001.mp3,001_Al-Fatihah.mp3, and001 الفاتحة.mp3are all valid and equivalent. - Supported formats: MP3 and WAV. MP3 is the sensible choice; a full 114-surah set at 128 kbps is roughly 2 GB.
- Folder names become the reciter names shown in the UI and dashboard, so name them the way you want to read them.
- Hidden files and folders (leading dot) and anything that does not match the pattern are skipped silently.
You do not need all 114 files; gaps are fine and the browser simply skips them.
Ayah timing data
To enable the on-device Arabic ayah badge (آية ١٥), accurate ayah navigation in the web dashboard, and ayah-level Hifz memorization repeat loops, place timing data under the /timings/ directory on the SD card:
/
├── Al-Husary/
│ ├── 001.mp3
│ └── ...
└── timings/
├── Al-Husary.atb # Consolidated binary archive for all 114 surahs (recommended)
└── Al-Husary/
├── 001.atb # Per-surah binary timing files (optional)
└── 001.json # Per-surah JSON timing files (fallback)
The loader prioritizes <reciter>.atb (a single ~27 KB binary archive with instant random access and zero dynamic memory allocations), followed by <reciter>/<surah>.atb, and falls back to JSON. Missing timing files leave ayah tracking inactive without interrupting audio playback.
Surah names
You only provide numbers; the firmware carries the full canonical list of the 114 surah names in Arabic script and renders them properly shaped on the display. That means the display never depends on how you spelled a filename, and Arabic filenames are unnecessary (though harmless).
The validation tool
The repository ships a script that checks a mounted card and can fix common naming issues:
# report problems only
./tools/prepare_sd_card_data.sh --check /run/media/you/SDCARD
# rename fixable files in place (e.g. 1.mp3 to 001.mp3)
./tools/prepare_sd_card_data.sh --rename /run/media/you/SDCARD
Playback behavior
- Within a reciter, playback advances to the next surah automatically at the end of a file.
- Seek works from the dashboard, including in variable bitrate MP3 files (the firmware indexes them properly; the details are an interesting read in seek and resume).
- The playback position is saved periodically and on every stop, so resume can pick up mid-surah even after power loss.
Swapping cards
The card is detected on insertion and the library rescans automatically; there is no need to reboot. Removing the card during playback stops file playback gracefully (radio streaming is unaffected, it never touches the card).