Update to new_checkshums.md5

new_checksums.md5 enables audio file naming and other audio related features.
This commit is contained in:
NeilClack
2026-08-21 10:03:31 -05:00
parent 3c9de0bee2
commit 39eb6d7bf7
+37 -33
View File
@@ -27,17 +27,17 @@ namespace radiantwave::audio {
// honored, anything else falls back to the Hz parsed from the filename, so // honored, anything else falls back to the Hz parsed from the filename, so
// the file's own name is always the safety net. // the file's own name is always the safety net.
struct AudioManifestEntry { struct AudioManifestEntry {
std::string filename; std::string filename;
std::string display_name; std::string display_name;
int solfeggio_frequency_hz = 0; int solfeggio_frequency_hz = 0;
std::string md5; std::string md5;
}; };
// Downloads audio assets from files.radiantwavetech.com in the background // Downloads audio assets from files.radiantwavetech.com in the background
// and keeps the database's audio_files table in sync with what is actually // and keeps the database's audio_files table in sync with what is actually
// on disk. // on disk.
// //
// Fetches checksums.md5, compares each entry against the local file's MD5, // Fetches new_checksums.md5, compares each entry against the local file's MD5,
// and re-downloads anything that is missing or whose checksum differs. // and re-downloads anything that is missing or whose checksum differs.
// Files present on disk but absent from the manifest are deleted, and the // Files present on disk but absent from the manifest are deleted, and the
// audio_files table is reconciled on every pass (and after each individual // audio_files table is reconciled on every pass (and after each individual
@@ -50,45 +50,49 @@ struct AudioManifestEntry {
// checksums are picked up while running. // checksums are picked up while running.
class AudioDownloader { class AudioDownloader {
public: public:
AudioDownloader() = default; AudioDownloader() = default;
~AudioDownloader(); ~AudioDownloader();
AudioDownloader(const AudioDownloader&) = delete; AudioDownloader(const AudioDownloader &) = delete;
AudioDownloader& operator=(const AudioDownloader&) = delete; AudioDownloader &operator=(const AudioDownloader &) = delete;
// Spawns the background thread. Safe to call repeatedly; only one worker // Spawns the background thread. Safe to call repeatedly; only one worker
// runs at a time. The manifest is reconciled against `db` on every pass. // runs at a time. The manifest is reconciled against `db` on every pass.
void start(db::DatabaseManager& db); void start(db::DatabaseManager &db);
// Signals the worker to stop and joins the thread. // Signals the worker to stop and joins the thread.
void shutdown(); void shutdown();
// Returns the current human-readable status for display (e.g. footer). // Returns the current human-readable status for display (e.g. footer).
std::string statusString() const; std::string statusString() const;
static constexpr const char* AUDIO_BASE_URL = "https://files.radiantwavetech.com/audio/"; static constexpr const char *AUDIO_BASE_URL =
static constexpr const char* MANIFEST_FILENAME = "checksums.md5"; "https://files.radiantwavetech.com/audio/";
static constexpr const char *MANIFEST_FILENAME = "new_checksums.md5";
private: private:
void run(); void run();
bool fetchManifest(std::vector<AudioManifestEntry>& out); bool fetchManifest(std::vector<AudioManifestEntry> &out);
bool downloadAndVerify(const std::string& filename, const std::string& expectedMd5, const std::string& displayName); bool downloadAndVerify(const std::string &filename,
const std::string &expectedMd5,
const std::string &displayName);
void setStatus(const std::string& msg); void setStatus(const std::string &msg);
void wait(std::chrono::seconds seconds); void wait(std::chrono::seconds seconds);
mutable std::mutex mutex_; mutable std::mutex mutex_;
std::condition_variable cv_; std::condition_variable cv_;
std::thread worker_; std::thread worker_;
std::atomic<bool> stop_{false}; std::atomic<bool> stop_{false};
std::string status_; std::string status_;
db::DatabaseManager* db_ = nullptr; db::DatabaseManager *db_ = nullptr;
}; };
// Parses checksums.md5 manifest text into entries. Blank lines and lines // Parses new_checksums.md5 manifest text into entries. Blank lines and lines
// starting with '#' are ignored. Lines that don't match a known format are // starting with '#' are ignored. Lines that don't match a known format are
// skipped. Returns false if no valid entries were found. // skipped. Returns false if no valid entries were found.
bool parseManifest(const std::string& text, std::vector<AudioManifestEntry>& out); bool parseManifest(const std::string &text,
std::vector<AudioManifestEntry> &out);
// Maps a frequency value in Hz to its internal solfeggio frequency id using // Maps a frequency value in Hz to its internal solfeggio frequency id using
// the same table the color palettes are seeded from (174/285->1, 396->2, // the same table the color palettes are seeded from (174/285->1, 396->2,
@@ -100,9 +104,9 @@ int frequencyIdForHz(int hz);
// "396Hz.wav" -> 396. Requires the digits to be followed by "Hz" // "396Hz.wav" -> 396. Requires the digits to be followed by "Hz"
// (case-insensitive); returns 0 when the name has no frequency (e.g. // (case-insensitive); returns 0 when the name has no frequency (e.g.
// "AlphaWaves.wav", "OriginalAudio.wav"). // "AlphaWaves.wav", "OriginalAudio.wav").
int hzFromFilename(const std::string& filename); int hzFromFilename(const std::string &filename);
// Computes the lowercase MD5 hex of a file, or an empty string on failure. // Computes the lowercase MD5 hex of a file, or an empty string on failure.
std::string computeFileMd5(const std::string& path); std::string computeFileMd5(const std::string &path);
} // namespace radiantwave::audio } // namespace radiantwave::audio