feat: audio mixer, Audio app, fix Installer crash

This commit is contained in:
daniel committed 2026-05-19 07:48:09 +02:00
1 parent 14da61bb0e
commit 8b8c8cee95
26 files changed
+1272 -373

No files matched your search

+26 -10
View File
@@ -1,33 +1,42 @@
/*
* Audio.hpp
* Audio syscall implementations
* Routes audio to Intel HDA or Bluetooth A2DP based on handle
* 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 <Drivers/USB/Bluetooth/Bluetooth.hpp>
#include <Drivers/USB/Bluetooth/A2dp.hpp>
#include <Sched/Scheduler.hpp>
#include "Syscall.hpp"
namespace Montauk {
// Audio handle convention:
// 0x00 - 0x0F : Intel HDA handles
// 0x100 : Bluetooth A2DP audio output
// 0x00 - 0x07 : Mixer virtual streams (one per opened audio handle)
// 0x100 : Bluetooth A2DP audio output (bypasses mixer for now)
static constexpr int AUDIO_HANDLE_BT = 0x100;
static int64_t Sys_AudioOpen(uint32_t sampleRate, uint8_t channels, uint8_t bitsPerSample) {
// If HDA is available, use it (primary output)
// HDA-backed mixer is the preferred output. The mixer keeps the HDA
// hardware stream open across virtual streams, so multiple apps can
// play simultaneously.
if (Drivers::Audio::IntelHda::IsInitialized()) {
return (int64_t)Drivers::Audio::IntelHda::Open(sampleRate, channels, bitsPerSample);
auto* proc = Sched::GetCurrentProcessPtr();
int pid = proc ? proc->pid : -1;
const char* name = proc ? proc->name : "?";
return (int64_t)Drivers::Audio::Mixer::Open(sampleRate, channels,
bitsPerSample, pid, name);
}
// Fallback: try Bluetooth audio if available
// Fallback: Bluetooth A2DP when no HDA controller is present.
if (Drivers::USB::Bluetooth::IsInitialized()) {
auto state = Drivers::USB::Bluetooth::A2dp::GetState();
if (state == Drivers::USB::Bluetooth::A2dp::State::Open ||
@@ -47,7 +56,7 @@ namespace Montauk {
Drivers::USB::Bluetooth::A2dp::StopStream();
return 0;
}
Drivers::Audio::IntelHda::Close(handle);
Drivers::Audio::Mixer::Close(handle);
return 0;
}
@@ -55,7 +64,7 @@ namespace Montauk {
if (handle == AUDIO_HANDLE_BT) {
return (int64_t)Drivers::USB::Bluetooth::A2dp::WriteAudio(data, size);
}
return (int64_t)Drivers::Audio::IntelHda::Write(handle, data, size);
return (int64_t)Drivers::Audio::Mixer::Write(handle, data, size);
}
static int64_t Sys_AudioCtl(int handle, int cmd, int value) {
@@ -77,14 +86,21 @@ namespace Montauk {
}
}
// Additional control commands for audio routing
if (cmd == AUDIO_CTL_GET_OUTPUT) return 0; // HDA
if (cmd == AUDIO_CTL_BT_STATUS) {
if (!Drivers::USB::Bluetooth::IsInitialized()) return 0;
return (int64_t)Drivers::USB::Bluetooth::A2dp::GetState();
}
return (int64_t)Drivers::Audio::IntelHda::Control(handle, cmd, value);
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);
}
};