77 lines
2.8 KiB
C++
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);
|
|
}
|
|
|
|
};
|