Files
MontaukOS/kernel/src/Api/Audio.hpp
T

77 lines
2.8 KiB
C++

/*
* 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 <cstdint>
#include <Drivers/Audio/IntelHda.hpp>
#include <Drivers/Audio/Mixer.hpp>
#include <Terminal/Terminal.hpp>
#include <Drivers/USB/Bluetooth/Bluetooth.hpp>
#include <Drivers/USB/Bluetooth/A2dp.hpp>
#include <Sched/Scheduler.hpp>
#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);
}
};