add device select to audio settings

This commit is contained in:
MihailRis 2025-11-04 19:47:35 +03:00
parent 25808d2b21
commit 88e61125d1
9 changed files with 91 additions and 10 deletions

View File

@ -24,10 +24,44 @@ function update_setting(x, id, name, postfix)
)
end
local initialized = false
function on_open()
if not initialized then
initialized = true
local token = audio.input.__get_core_token()
document.root:add("<container id='tm' />")
local prev_amplitude = 0.0
document.tm:setInterval(16, function()
audio.input.fetch_input(token)
local amplitude = audio.input.get_max_amplitude()
if amplitude > 0.0 then
amplitude = math.sqrt(amplitude)
end
document.input_volume_inner.size = {
prev_amplitude *
document.input_volume_outer.size[1],
document.input_volume_outer.size[2]
}
prev_amplitude = amplitude * 0.25 + prev_amplitude * 0.75
end)
end
create_setting("audio.volume-master", "Master Volume", 0.01)
create_setting("audio.volume-regular", "Regular Sounds", 0.01)
create_setting("audio.volume-ui", "UI Sounds", 0.01)
create_setting("audio.volume-ambient", "Ambient", 0.01)
create_setting("audio.volume-music", "Music", 0.01)
document.root:add("<select id='input_device_select' "..
"onselect='function(opt) audio.set_input_device(opt) end'/>")
document.root:add("<container id='input_volume_outer' color='#000000' size='4'>"
.."<container id='input_volume_inner' color='#00FF00FF' size='4'/>"
.."</container>")
local selectbox = document.input_device_select
local devices = {}
local names = audio.get_input_devices_names()
for i, name in ipairs(names) do
table.insert(devices, {value=name, text=name})
end
selectbox.options = devices
selectbox.value = audio.get_input_info().device_specifier
end

View File

@ -1,7 +1,7 @@
<container id="%{id}" size="32" tooltip="%{text}"
onclick="events.emit('core:open_traceback', '%{traceback}')">
<image src="gui/%{type}" size="32"/>
<label pos="36,2" sizefunc="-1,-1">%{text}</label>
<label pos="36,2" size-func="-1,-1">%{text}</label>
<image src="gui/cross" interactive="true" size="16" gravity="top-right"
onclick="document['%{id}']:destruct()"></image>
</container>

View File

@ -6,7 +6,7 @@
onclick='%{open_func}("%{filename}")'
markup='md'
tooltip='%{unit}'
sizefunc="-1,-1">
size-func="-1,-1">
[#FFFFFF80]%{path}[#FFFFFFFF]%{name}
</label>
</container>

View File

@ -1,27 +1,43 @@
local audio_input_tokens_store = {}
local _base64_encode_urlsafe = base64.encode_urlsafe
local _random_bytes = random.bytes
local core_token = _base64_encode_urlsafe(_random_bytes(18))
local audio_input_tokens_store = {[core_token] = "core"}
audio.input = {}
local _gui_confirm = gui.confirm
local _base64_encode_urlsafe = base64.encode_urlsafe
local _random_bytes = random.bytes
local _debug_pack_by_frame = debug.get_pack_by_frame
local _audio_fetch_input = audio.__fetch_input
audio.__fetch_input = nil
local MAX_FETCH = 44100 * 4
local MAX_AMPLITUDE = 32768
local total_fetch = Bytearray()
local max_amplitude = 0.0
function audio.__reset_fetch_buffer()
total_fetch:clear()
max_amplitude = 0.0
end
function audio.fetch_input(token, size)
function audio.input.get_max_amplitude()
return max_amplitude / MAX_AMPLITUDE
end
function audio.input.fetch_input(token, size)
size = size or MAX_FETCH
if audio_input_tokens_store[token] then
if #total_fetch >= size then
return total_fetch:slice(1, size)
end
total_fetch:append(_audio_fetch_input(size - #total_fetch))
local fetched = _audio_fetch_input(size - #total_fetch)
if not fetched then
return
end
for i, sample in ipairs(I16view(fetched)) do
max_amplitude = math.max(math.abs(sample))
end
total_fetch:append(fetched)
return total_fetch:slice()
end
error("access denied")
@ -38,3 +54,10 @@ function audio.input.request_open(callback)
menu:reset()
end)
end
function audio.input.__get_core_token()
local caller = _debug_pack_by_frame(1)
if caller == "core" then
return core_token
end
end

View File

@ -119,6 +119,8 @@ function on_hud_open()
hud.default_hand_controller = update_hand
debug.print(audio.get_input_devices_names())
stream = audio.PCMStream(44100, 1, 16)
stream:share("test-stream")
streamid = audio.play_stream_2d("test-stream", 2.0, 1.0, "ui")
@ -147,7 +149,9 @@ function on_hud_render()
end
if input_access_token then
local bytes = audio.fetch_input(input_access_token)
stream:feed(bytes)
local bytes = audio.input.fetch_input(input_access_token)
if bytes then
stream:feed(bytes)
end
end
end

View File

@ -79,6 +79,13 @@ ALInputDevice::ALInputDevice(
channels(channels),
bitsPerSample(bitsPerSample),
sampleRate(sampleRate) {
const ALCchar* deviceName = alcGetString(device, ALC_CAPTURE_DEVICE_SPECIFIER);
if (deviceName) {
deviceSpecifier = std::string(deviceName);
} else {
logger.warning() << "could not retrieve input device specifier";
}
}
ALInputDevice::~ALInputDevice() {
@ -108,6 +115,10 @@ uint ALInputDevice::getBitsPerSample() const {
return bitsPerSample;
}
const std::string& ALInputDevice::getDeviceSpecifier() const {
return deviceSpecifier;
}
size_t ALInputDevice::read(char* buffer, size_t bufferSize) {
ALCint samplesCount = 0;
alcGetIntegerv(device, ALC_CAPTURE_SAMPLES, sizeof(samplesCount), &samplesCount);

View File

@ -104,6 +104,7 @@ namespace audio {
uint getChannels() const override;
uint getSampleRate() const override;
uint getBitsPerSample() const override;
const std::string& getDeviceSpecifier() const override;
size_t read(char* buffer, size_t bufferSize) override;
private:
@ -112,6 +113,7 @@ namespace audio {
uint channels;
uint bitsPerSample;
uint sampleRate;
std::string deviceSpecifier;
};
/// @brief AL source adapter

View File

@ -127,7 +127,12 @@ namespace audio {
/// @return 8 or 16
virtual uint getBitsPerSample() const = 0;
/// @brief Read available data to buffer.
/// @return size of data received or PCMStream::ERROR in case of error
virtual size_t read(char* buffer, size_t bufferSize) = 0;
/// @brief Get device specifier string
virtual const std::string& getDeviceSpecifier() const = 0;
};
/// @brief audio::PCMStream is a data source for audio::Stream

View File

@ -441,7 +441,9 @@ static int l_audio_get_input_info(lua::State* L) {
if (device == nullptr) {
return 0;
}
lua::createtable(L, 0, 3);
lua::createtable(L, 0, 4);
lua::pushlstring(L, device->getDeviceSpecifier());
lua::setfield(L, "device_specifier");
lua::pushinteger(L, device->getChannels());
lua::setfield(L, "channels");
lua::pushinteger(L, device->getSampleRate());