Refactor metadata and internal data structures

Replace Metadata.h with Containers.h, introducing a HashTable
implementation with SIMD acceleration and specialized track tracking.
Cleanup PlayerEngine logic by merging it into the playback flow and
refactoring several internal API signatures.
This commit is contained in:
2026-06-20 22:04:26 +02:00
parent 80bffc0fdd
commit 20c0f9744f
14 changed files with 345 additions and 162 deletions
+88
View File
@@ -0,0 +1,88 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
#include <string>
#include <taglib/tag.h>
struct Metadata {
TagLib::String artist;
TagLib::String title;
TagLib::String album;
TagLib::String albumArtist;
unsigned int year;
TagLib::VariantList artwork;
TagLib::String genre;
unsigned int trackNr;
double length;
std::string format;
unsigned int sampleRate;
unsigned int bitRate;
};
struct Track {
TagLib::String artist;
TagLib::String title;
TagLib::String album;
unsigned int trackNr;
unsigned int length;
std::string filePath;
std::string_view artwork;
std::string_view genre;
std::string format;
};
using trackPtr = std::shared_ptr<Track>;
class HashTable {
public:
static constexpr uint8_t EMPTY = 0x80;
static constexpr uint8_t DELETED = 0xFE;
explicit HashTable ( size_t capacity = 64 );
// delete disabled - requires rehash
HashTable ( const HashTable & ) = delete;
HashTable &operator= ( const HashTable & ) = delete;
HashTable ( HashTable && ) noexcept = default;
HashTable &operator= ( HashTable && ) noexcept = default;
void ht_insert ( const std::string &key, trackPtr track );
trackPtr ht_lookup ( const std::string &key ) const;
bool ht_delete ( const std::string &key );
std::vector<std::string> listAll () const;
void save ( const std::string &filename ) const;
std::vector<std::unique_ptr<Track>> load ( const std::string &filename );
std::size_t size () const noexcept { return size_; }
std::size_t capacity () const noexcept { return ctrl_.size(); }
private:
static constexpr double MAX_LOAD = 0.75;
static constexpr std::size_t GROUP_SIZE = 32;
struct Entry {
std::string key;
uint64_t hash = 0;
trackPtr track;
};
// helpers
static uint64_t hashString ( const std::string &key ) noexcept;
static uint8_t fingerprint ( uint64_t hash ) noexcept;
std::ptrdiff_t probe ( const std::string &key, uint64_t hash, bool insert ) const noexcept;
void rehash ( std::size_t newCapacity );
std::vector<uint8_t> ctrl_;
std::vector<Entry> entries_;
std::size_t size_ = 0;
double loadFactor_ = static_cast<double> ( size_ ) / static_cast<double> ( ctrl_.size());
}; // Class HashTable
+4 -3
View File
@@ -1,6 +1,6 @@
#pragma once
#include "Metadata.h"
#include "Containers.h"
#include <sqlite3.h>
@@ -10,8 +10,9 @@ class Database {
public:
Database( const char* filename, sqlite3** db );
~Database();
void fetch( const std::string& query );
void fetchAlbum( const std::string& album );
void fetch( const std::string& query ) const;
void fetchAlbum( const std::string& album ) const;
void fetchAll() const;
void addSong( );
private:
sqlite3* db_;
+7 -7
View File
@@ -1,22 +1,22 @@
#pragma once
#include "Containers.h"
#include <filesystem>
#include <vector>
#include <string>
#define MUSIC_FOLDER = {"data/"};
namespace fs = std::filesystem;
class File {
public:
void importFile( std::string fileName );
void importFolder( std::string folderPath );
std::vector<std::string> filenames_;
void importFolder( const std::string& folderPath, std::vector<Track>& tracks );
void readFileTag( const char* fileName );
std::string parseFiletype( const std::string& path );
private:
std::string path_;
fs::path musicFolder_ MUSIC_FOLDER;
fs::path musicFolder_ = "data/";
std::string fileName_;
fs::path fp_ = musicFolder_ / fileName_;
};
std::string_view parseFiletype( std::string_view path );
-28
View File
@@ -1,28 +0,0 @@
#pragma once
#include <string>
#include <taglib/tag.h>
struct Metadata {
TagLib::String artist;
TagLib::String title;
TagLib::String album;
TagLib::String albumArtist;
unsigned int year;
TagLib::VariantList artwork;
TagLib::String genre;
unsigned int trackNr;
double length;
std::string format;
unsigned int sampleRate;
unsigned int bitRate;
};
struct Track {
std::string_view artist;
std::string_view title;
std::string_view album;
unsigned int trackNr;
unsigned int length;
const char *filePath;
};
+1 -1
View File
@@ -28,7 +28,7 @@ class PlaybackEngine {
void seek ( ma_uint64 frame );
int isFinished () const;
ma_uint64 getPosition ();
uint64_t getPosition ();
private:
ma_device device_;
+14 -8
View File
@@ -1,6 +1,6 @@
#pragma once
#include "../include/Metadata.h"
#include "../include/Containers.h"
#include "../include/PlaybackEngine.h"
#include "../include/miniaudio.h"
@@ -8,7 +8,8 @@
#include <string>
#include <vector>
using Queue = std::vector<Track>;
using trackVec = std::vector<Track>;
using ht = HashTable;
class Player {
public:
@@ -33,16 +34,16 @@ class Player {
virtual std::string &getAlbum () const;
virtual unsigned int getTrackNr () const;
// Player Queue
Queue getQueue () const;
Queue clearQueue ();
// Player trackVec
trackVec getQueue () const;
trackVec clearQueue ();
void addToQueue ( Track &track );
Queue rempveFromQueue ( Track &track );
Queue shuffleQueue ();
trackVec rempveFromQueue ( Track &track );
trackVec shuffleQueue ();
protected:
PlaybackEngine PE_;
Queue queue_;
trackVec queue_;
private:
std::string artist_;
@@ -53,4 +54,9 @@ class Player {
unsigned int samplerate_ = 48000;
unsigned int channels_ = 2;
trackVec tracks;
ht songs;
ht artists;
ht albums;
};
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include "miniaudio.h"
class PlayerEngine {
private:
ma_engine engine_;
ma_engine_config engineConfig_;
ma_device device_;
ma_device_config deviceConfig_;
unsigned int sampleRate_;
unsigned int channels_ = 2;
ma_format format_ = ma_format_unknown;
ma_context context_;
public:
PlayerEngine();
PlayerEngine( unsigned int sampleRate, unsigned int channels, ma_format format );
~PlayerEngine();
ma_device getDevice() const;
unsigned int getChannels() const;
unsigned int getSampleRate() const;
ma_format getFormat() const;
void setDevice( ma_device device );
void setSampleRate( unsigned int sampleRate );
void setChannels( unsigned int channels );
void setFormat( ma_format format );
ma_device_data_proc data_callback();
void configureDevice( ma_context& context );
void initDevice ();
void initEngine();
};
+15 -9
View File
@@ -1,20 +1,26 @@
#pragma once
#include "Metadata.h"
#include "containers.h"
//#include "file.h"
#include <filesystem>
#include <memory>
#include <taglib/tstring.h>
#include <taglib/fileref.h>
#include <taglib/tvariant.h>
class Tag {
public:
void readTag( TagLib::FileName fileName );
Metadata getMetadata() const;
namespace fs = std::filesystem;
const std::string& getFilePath() const;
const auto getArtwork() const;
class tag {
public:
void readtag( TagLib::filename filename );
metadata getmetadata() const;
const std::string& getfilepath() const;
const auto getartwork() const;
private:
Metadata metadata_;
std::string filePath_;
metadata metadata_;
std::string filepath_;
fs::path musicdir = music_folder;
};