Skip to content

Platform Abstraction Module

Cross-platform OS and filesystem abstraction layer for AudioLab.

Overview

This module provides platform-agnostic APIs for: - Platform detection (OS, architecture, compiler) - System information (CPU, memory, OS version) - Standard directory paths - File and directory operations

Components

🖥️ OS Abstraction (04_13_00_os_abstraction/)

Platform Detection

#include <audiolab/platform_abstraction/os_abstraction/platform_detection.hpp>

// Automatically defined macros:
// AUDIOLAB_WINDOWS, AUDIOLAB_MACOS, AUDIOLAB_LINUX
// AUDIOLAB_X64, AUDIOLAB_ARM64
// AUDIOLAB_MSVC, AUDIOLAB_CLANG, AUDIOLAB_GCC

System Information

#include <audiolab/platform_abstraction/os_abstraction/system_info.hpp>

using namespace audiolab;

// CPU info
uint32 cores = SystemInfo::cpu_count();
std::string brand = SystemInfo::cpu_brand();

// Memory info
uint64 total_ram = SystemInfo::total_memory_bytes();
uint64 available = SystemInfo::available_memory_bytes();

// OS info
std::string os = SystemInfo::os_name();
std::string version = SystemInfo::os_version();

Platform Paths

#include <audiolab/platform_abstraction/os_abstraction/platform_paths.hpp>

// User directories
std::string home = PlatformPaths::user_home();
std::string docs = PlatformPaths::user_documents();

// Application directories
std::string app_data = PlatformPaths::app_data();        // AppData/Roaming, ~/Library, ~/.config
std::string cache = PlatformPaths::app_cache();          // Cache directory

// Plugin directories
std::string presets = PlatformPaths::plugin_presets("reverb");
std::string vst3 = PlatformPaths::vst3_directory();

📁 Filesystem (04_13_02_filesystem/)

Path Manipulation

#include <audiolab/platform_abstraction/filesystem/path.hpp>

using namespace audiolab;

// Create path
Path p = "data/presets";
Path joined = p / "reverb" / "hall.preset";

// Query path
std::string str = p.string();           // Portable (forward slashes)
std::string native = p.native_string(); // Platform-specific separators
bool exists = p.exists();
bool is_file = p.is_file();

// Path components
Path parent = p.parent();
Path filename = p.filename();
Path ext = p.extension();
Path stem = p.stem();

// Manipulation
p.replace_extension(".json");
p.append("backup");

File Operations

#include <audiolab/platform_abstraction/filesystem/file_operations.hpp>

// Read/Write
std::string text = FileOperations::read_text("file.txt");
FileOperations::write_text("output.txt", "Hello!");

std::vector<uint8> data = FileOperations::read_binary("data.bin");
FileOperations::write_binary("out.bin", data);

// Copy/Move
FileOperations::copy("src.txt", "dst.txt");
FileOperations::move("old.txt", "new.txt");

// Attributes
uint64 size = FileOperations::file_size("file.txt");
bool readonly = FileOperations::is_readonly("file.txt");

// Atomic write (safe for crashes)
FileOperations::write_text_atomic("config.json", data);

// File locking
FileOperations::create_lock("database.db");
FileOperations::remove_lock("database.db");

Directory Operations

#include <audiolab/platform_abstraction/filesystem/directory_operations.hpp>

// Create/Remove
DirectoryOperations::create_recursive("path/to/dir");
DirectoryOperations::remove_recursive("path/to/dir");

// List contents
auto files = DirectoryOperations::list_files("dir", /*recursive=*/true);
auto dirs = DirectoryOperations::list_directories("dir");

// Find files
auto presets = DirectoryOperations::find_files("dir", "*.preset", true);
auto wavs = DirectoryOperations::find_by_extension("dir", ".wav", true);

// Stats
uint64 size = DirectoryOperations::directory_size("dir");
size_t count = DirectoryOperations::count_files("dir", true);

// Copy/Move
DirectoryOperations::copy_directory("src", "dst");
DirectoryOperations::move_directory("old", "new");

Platform-Specific Behavior

Windows

  • Path separator: \ (accepts both \ and /)
  • App data: %APPDATA%\AudioLab
  • Temp: %TEMP%
  • VST3: C:\Program Files\Common Files\VST3

macOS

  • Path separator: /
  • App data: ~/Library/Application Support/AudioLab
  • Temp: /tmp
  • VST3: ~/Library/Audio/Plug-Ins/VST3
  • AU: ~/Library/Audio/Plug-Ins/Components

Linux

  • Path separator: /
  • App data: ~/.config/audiolab (or $XDG_CONFIG_HOME/audiolab)
  • Cache: ~/.cache/audiolab (or $XDG_CACHE_HOME/audiolab)
  • Temp: /tmp
  • VST3: ~/.vst3

Building

cd 04_13_platform_abstraction
cmake -B build -G "Visual Studio 17 2022" -A x64  # Windows
# or
cmake -B build                                     # macOS/Linux

cmake --build build --config Release
ctest --test-dir build -C Release

Tests

All tests pass on Windows (MSVC), macOS (Clang), and Linux (GCC):

  • test_platform_detection - Platform/architecture/compiler detection
  • test_paths - Path manipulation and platform paths
  • test_file_operations - File I/O operations
  • test_directory_operations - Directory operations

Run tests:

cd build
ctest -C Release --output-on-failure

Example

See examples/filesystem_demo.cpp for complete demo.

./build/Release/filesystem_demo

Design Decisions

Why std::filesystem?

  • C++17 standard, well-tested
  • No external dependencies
  • Good performance
  • Platform-specific code isolated in .cpp files

Why wrapper classes?

  • Cleaner API (e.g., Path::exists() vs std::filesystem::exists(path))
  • Additional utilities not in standard (e.g., find_by_pattern, atomic writes)
  • Consistent error handling

Path Separator Handling

  • Input: accepts both / and \ on all platforms
  • Output:
  • string(): portable (forward slashes)
  • native_string(): platform-specific

API Stability

Stable APIs (safe to use): - Platform detection macros - SystemInfo queries - PlatformPaths standard directories - Path manipulation - Basic file/directory operations

⚠️ Experimental APIs: - File locking (platform-dependent behavior) - Wait/notify operations (C++20 only)

Future Enhancements

  • File watching (inotify, FSEvents, ReadDirectoryChangesW)
  • Memory-mapped files
  • Symbolic link support
  • File permissions (POSIX/Windows ACLs)
  • Asynchronous I/O

License

Part of AudioLab. See top-level LICENSE file.