/* * Audio.hpp * Audio syscall implementations * Routes audio through the software mixer to the active hardware backend * (Intel HDA or Bluetooth A2DP). * Copyright (c) 2026 Daniel Hammer */ #pragma once #include #include #include #include #include #include #include #include "Syscall.hpp" namespace montauk::abi { static int64_t Sys_AudioOpen(uint32_t sampleRate, uint8_t channels, uint8_t bitsPerSample) { auto* proc = Sched::GetCurrentProcessPtr(); int pid = proc ? proc->pid : -1; const char* name = proc ? proc->name : "?"; // Every application gets a mixer stream regardless of the selected // device. The mixer performs one shared resample/mix pass and routes it // to HDA or A2DP, allowing concurrent Bluetooth playback and live // switching without invalidating application handles. if (Drivers::Audio::Mixer::IsOutputAvailable( Drivers::Audio::Mixer::Output::Hda) || Drivers::Audio::Mixer::IsOutputAvailable( Drivers::Audio::Mixer::Output::Bluetooth)) { return (int64_t)Drivers::Audio::Mixer::Open(sampleRate, channels, bitsPerSample, pid, name); } return NoDevice; } static int64_t Sys_AudioClose(int handle) { Drivers::Audio::Mixer::Close(handle); return Success; } static int64_t Sys_AudioWrite(int handle, const uint8_t* data, uint32_t size) { return (int64_t)Drivers::Audio::Mixer::Write(handle, data, size); } static int64_t Sys_AudioCtl(int handle, int cmd, int value) { if (cmd == AUDIO_CTL_GET_OUTPUT) return (int)Drivers::Audio::Mixer::GetOutput(); if (cmd == AUDIO_CTL_SET_OUTPUT) return Drivers::Audio::Mixer::SetOutput( (Drivers::Audio::Mixer::Output)value); if (cmd == AUDIO_CTL_BT_STATUS) { if (!Drivers::USB::Bluetooth::IsInitialized()) return 0; if (Drivers::USB::Bluetooth::A2dp::IsReady()) return 2; return Drivers::USB::Bluetooth::A2dp::GetState() == Drivers::USB::Bluetooth::A2dp::State::Idle ? 0 : 1; } return (int64_t)Drivers::Audio::Mixer::Control(handle, cmd, value); } static int64_t Sys_AudioList(AudioStreamInfo* buf, int maxCount) { return (int64_t)Drivers::Audio::Mixer::List(buf, maxCount); } static int64_t Sys_AudioWait(uint64_t prevSerial, uint64_t timeoutMs) { return (int64_t)Drivers::Audio::Mixer::Wait(prevSerial, timeoutMs); } };