// This file is part of the 64k demo project. // It implements the production audio backend using miniaudio. // Moved from audio.cc to enable backend abstraction for testing. #include "miniaudio_backend.h" #include "synth.h" #include // Static callback for miniaudio (C API requirement) void MiniaudioBackend::audio_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) { (void)pDevice; (void)pInput; float* fOutput = (float*)pOutput; synth_render(fOutput, (int)frameCount); } MiniaudioBackend::MiniaudioBackend() : initialized_(false) { } MiniaudioBackend::~MiniaudioBackend() { if (initialized_) { shutdown(); } } void MiniaudioBackend::init() { if (initialized_) { return; } ma_device_config config = ma_device_config_init(ma_device_type_playback); config.playback.format = ma_format_f32; config.playback.channels = 2; config.sampleRate = 32000; config.dataCallback = MiniaudioBackend::audio_callback; config.pUserData = this; if (ma_device_init(NULL, &config, &device_) != MA_SUCCESS) { printf("Failed to open playback device.\n"); return; } initialized_ = true; } void MiniaudioBackend::start() { if (!initialized_) { printf("Cannot start: backend not initialized.\n"); return; } if (ma_device_start(&device_) != MA_SUCCESS) { printf("Failed to start playback device.\n"); ma_device_uninit(&device_); initialized_ = false; return; } } void MiniaudioBackend::shutdown() { if (!initialized_) { return; } ma_device_stop(&device_); ma_device_uninit(&device_); initialized_ = false; }