feat: audio mixer, Audio app, fix Installer crash
This commit is contained in:
+26
-10
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -19,11 +19,13 @@ namespace Montauk {
|
||||
auto* rep = &CrashReport::g_reports[oldestIdx];
|
||||
|
||||
out->pid = rep->pid;
|
||||
for (int i = 0; i < 64 && rep->processName[i]; i++) out->processName[i] = rep->processName[i];
|
||||
out->processName[63] = '\0';
|
||||
int pn;
|
||||
for (pn = 0; pn < 63 && rep->processName[pn]; pn++) out->processName[pn] = rep->processName[pn];
|
||||
out->processName[pn] = '\0';
|
||||
out->exceptionVector = rep->exceptionVector;
|
||||
for (int i = 0; i < 32 && rep->exceptionName[i]; i++) out->exceptionName[i] = rep->exceptionName[i];
|
||||
out->exceptionName[31] = '\0';
|
||||
int en;
|
||||
for (en = 0; en < 31 && rep->exceptionName[en]; en++) out->exceptionName[en] = rep->exceptionName[en];
|
||||
out->exceptionName[en] = '\0';
|
||||
out->faultingAddress = rep->faultingAddress;
|
||||
out->instructionPointer = rep->instructionPointer;
|
||||
out->stackPointer = rep->stackPointer;
|
||||
|
||||
@@ -334,6 +334,12 @@ namespace Montauk {
|
||||
return Sys_AudioWrite((int)frame->arg1, (const uint8_t*)frame->arg2, (uint32_t)frame->arg3);
|
||||
case SYS_AUDIOCTL:
|
||||
return Sys_AudioCtl((int)frame->arg1, (int)frame->arg2, (int)frame->arg3);
|
||||
case SYS_AUDIOLIST:
|
||||
if ((int64_t)frame->arg2 < 0) return -1;
|
||||
if (!UserMemory::Range(frame->arg1, (uint64_t)frame->arg2 * sizeof(AudioStreamInfo), true)) return -1;
|
||||
return Sys_AudioList((AudioStreamInfo*)frame->arg1, (int)frame->arg2);
|
||||
case SYS_AUDIOWAIT:
|
||||
return Sys_AudioWait(frame->arg1, frame->arg2);
|
||||
case SYS_BTSCAN:
|
||||
if ((int64_t)frame->arg2 < 0) return -1;
|
||||
if (!UserMemory::Range(frame->arg1, (uint64_t)frame->arg2 * sizeof(BtScanResult), true)) return -1;
|
||||
|
||||
@@ -157,14 +157,23 @@ namespace Montauk {
|
||||
static constexpr uint64_t SYS_AUDIOWRITE = 82;
|
||||
static constexpr uint64_t SYS_AUDIOCTL = 83;
|
||||
|
||||
// Audio control commands (for SYS_AUDIOCTL)
|
||||
static constexpr int AUDIO_CTL_SET_VOLUME = 0;
|
||||
static constexpr int AUDIO_CTL_GET_VOLUME = 1;
|
||||
static constexpr int AUDIO_CTL_GET_POS = 2;
|
||||
static constexpr int AUDIO_CTL_PAUSE = 3;
|
||||
static constexpr int AUDIO_CTL_GET_OUTPUT = 4; // 0=HDA, 1=Bluetooth
|
||||
static constexpr int AUDIO_CTL_SET_OUTPUT = 5; // Switch audio output
|
||||
static constexpr int AUDIO_CTL_BT_STATUS = 6; // Get Bluetooth connection status
|
||||
// Audio control commands (for SYS_AUDIOCTL).
|
||||
//
|
||||
// Commands 0..3 act on the stream named by the handle argument.
|
||||
// Commands 7..10 act on the global master and ignore the handle.
|
||||
static constexpr int AUDIO_CTL_SET_VOLUME = 0;
|
||||
static constexpr int AUDIO_CTL_GET_VOLUME = 1;
|
||||
static constexpr int AUDIO_CTL_GET_POS = 2;
|
||||
static constexpr int AUDIO_CTL_PAUSE = 3;
|
||||
static constexpr int AUDIO_CTL_GET_OUTPUT = 4; // 0=HDA, 1=Bluetooth
|
||||
static constexpr int AUDIO_CTL_SET_OUTPUT = 5; // Switch audio output
|
||||
static constexpr int AUDIO_CTL_BT_STATUS = 6; // Get Bluetooth status
|
||||
static constexpr int AUDIO_CTL_SET_MASTER_VOLUME = 7; // 0-100
|
||||
static constexpr int AUDIO_CTL_GET_MASTER_VOLUME = 8;
|
||||
static constexpr int AUDIO_CTL_SET_MUTE = 9; // 0/1, per-stream
|
||||
static constexpr int AUDIO_CTL_GET_MUTE = 10;
|
||||
static constexpr int AUDIO_CTL_SET_MASTER_MUTE = 11;
|
||||
static constexpr int AUDIO_CTL_GET_MASTER_MUTE = 12;
|
||||
|
||||
/* Bluetooth.hpp */
|
||||
static constexpr uint64_t SYS_BTSCAN = 84;
|
||||
@@ -230,6 +239,10 @@ namespace Montauk {
|
||||
/* Net.hpp */
|
||||
static constexpr uint64_t SYS_NETSTATUS = 125;
|
||||
|
||||
/* Audio.hpp */
|
||||
static constexpr uint64_t SYS_AUDIOLIST = 128;
|
||||
static constexpr uint64_t SYS_AUDIOWAIT = 129;
|
||||
|
||||
static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024;
|
||||
|
||||
static constexpr uint32_t IPC_SIGNAL_READABLE = 1u << 0;
|
||||
@@ -311,6 +324,20 @@ namespace Montauk {
|
||||
uint64_t serial;
|
||||
};
|
||||
|
||||
// One entry per active mixer stream; returned by SYS_AUDIOLIST.
|
||||
struct AudioStreamInfo {
|
||||
int32_t handle;
|
||||
int32_t ownerPid;
|
||||
char name[64];
|
||||
uint32_t sampleRate;
|
||||
uint8_t channels;
|
||||
uint8_t bitsPerSample;
|
||||
uint8_t volume; // 0-100
|
||||
uint8_t muted; // 0/1
|
||||
uint8_t paused; // 0/1
|
||||
uint8_t _pad[7];
|
||||
};
|
||||
|
||||
// Window server shared types
|
||||
struct WinEvent {
|
||||
uint8_t type; // 0=key, 1=mouse, 2=resize, 3=close, 4=scale
|
||||
|
||||
Reference in New Issue
Block a user