diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5a01a618..121c5a60 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -2,7 +2,7 @@ name: x86-64 AppImage on: push: - branches: [ "main", "dev", "release-**"] + branches: [ "main", "release-**"] pull_request: branches: [ "main", "dev" ] diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index f8fe3dfa..bb40a7ad 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -2,7 +2,7 @@ name: Macos Build on: push: - branches: [ "main", "dev", "release-**"] + branches: [ "main", "release-**"] pull_request: branches: [ "main", "dev" ] diff --git a/.github/workflows/windows-clang.yml b/.github/workflows/windows-clang.yml index cdf354dd..cb486409 100644 --- a/.github/workflows/windows-clang.yml +++ b/.github/workflows/windows-clang.yml @@ -2,7 +2,7 @@ name: Windows Build (CLang) on: push: - branches: [ "main", "dev", "release-**"] + branches: [ "main", "release-**"] pull_request: branches: [ "main", "dev" ] diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e5ee5a69..afeed757 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -2,7 +2,7 @@ name: MSVC Build on: push: - branches: [ "main", "dev", "release-**"] + branches: [ "main", "release-**"] pull_request: branches: [ "main", "dev" ] diff --git a/doc/en/audio.md b/doc/en/audio.md index cacd7107..09510402 100644 --- a/doc/en/audio.md +++ b/doc/en/audio.md @@ -203,3 +203,79 @@ audio.count_speakers() -> integer -- get current number of playing streams audio.count_streams() -> integer ``` + +### audio.PCMStream + +```lua +-- Creating a PCM data source +local stream = audio.PCMStream( + -- Sample rate + sample_rate: integer, + -- Number of channels (1 - mono, 2 - stereo) + channels: integer, + -- Number of bits per sample (8 or 16) + bits_per_sample: integer, +) + +-- Feeding PCM data into the stream +stream:feed( + -- PCM data to be fed into the stream + data: Bytearray +) + +-- Publishing the PCM data source for use by the engine systems +stream:share( + -- Alias of the audio stream, which can be referenced in audio.play_stream + alias: string +) + +-- Creating a sound from the PCM data in the stream +stream:create_sound( + -- Name of the created sound + name: string +) +``` + +### Audio Recording + +```lua +-- Requests access to audio recording +-- On confirmation, the callback receives a token for use in audio.input.fetch +audio.input.request_open(callback: function(string)) + +-- Reads new PCM audio input data +audio.input.fetch( + -- Token obtained through audio.input.request_open + access_token: string, + -- Maximum buffer size in bytes (optional) + [optional] max_read_size: integer +) +``` + +### Example of Audio Generation: + +```lua +-- For working with 16-bit samples, use a U16view over Bytearray +-- Example: +local max_amplitude = 32767 +local sample_rate = 44100 +local total_samples = sample_rate * 5 -- 5 seconds of mono +local bytes = Bytearray(total_samples * 2) -- 5 seconds of 16-bit mono +local samples = I16view(bytes) + +local frequency_hz = 400 +for i=1, total_samples do + local value = math.sin(i * math.pi * 2 / sample_rate * frequency_hz) + samples[i] = value * max_amplitude +end + +local stream_name = "test-stream" +local stream = audio.PCMStream(sample_rate, 1, 16) +stream:feed(bytes) +stream:share(stream_name) + +local volume = 1.0 +local pitch = 1.0 +local channel = "ui" +audio.play_stream_2d(stream_name, volume, pitch, channel) +``` diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md index 2da6843c..80750501 100644 --- a/doc/en/scripting/ui.md +++ b/doc/en/scripting/ui.md @@ -196,6 +196,10 @@ Here, *color* can be specified in the following ways: | data:update() | applies changes to the canvas and uploads it to the GPU | | data:set_data(data: table) | replaces pixel data (width * height * 4 numbers) | | data:create_texture(name: str) | creates and shares texture to renderer | +| data:unbind_texture() | unbinds the texture from the canvas | +| data:mul(*color* or Canvas) | multiplies a color by the specified color or canvas | +| data:add(*color* or Canvas) | adds a color or another canvas to a color | +| data:sub(*color* or Canvas) | subtracts a color or another canvas to a color | ## Inline frame (iframe) diff --git a/doc/ru/audio.md b/doc/ru/audio.md index 1fce6c35..8291e7ba 100644 --- a/doc/ru/audio.md +++ b/doc/ru/audio.md @@ -29,6 +29,7 @@ Доступ к спикерам производится по целочисленным id, которые не повторяются за время работы движка, следует избегать хранения прямых указателей на объекты класса. Нумерация ID спикеров начинается с 1. ID 0 означает невозможность воспроизведения, по какой-либо причине. + ### Звук (Sound) Звуковые данные загруженные в память для возможности одновременного воспроизведения из нескольких источников. Может предоставлять доступ к PCM данным. @@ -203,3 +204,79 @@ audio.count_speakers() -> integer -- получить текущее число проигрываемых аудио-потоков audio.count_streams() -> integer ``` + +### audio.PCMStream + +```lua +-- создание источника PCM данных +local stream = audio.PCMStream( + -- частота дискретизации + sample_rate: integer, + -- число каналов (1 - моно, 2 - стерео) + channels: integer, + -- число бит на сэмпл (8 или 16) + bits_per_sample: integer, +) + +-- подача PCM данных в поток +stream:feed( + -- PCM данные для подачи в поток + data: Bytearray +) + +-- публикация источника PCM данных для использования системами движка +stream:share( + -- имя потокового аудио, которое можно будет указать в audio.play_stream + alias: string +) + +-- создание звука из имеющихся в потоке PCM данных +stream:create_sound( + -- имя создаваемого звука + name: string +) +``` + +### Запись звука + +```lua +-- запрашивает доступ к записи звука +-- при подтверждении, в callback передаётся токен для использовании в audio.input.fetch +audio.input.request_open(callback: function(string)) + +-- читает новые PCM данные аудио ввода +audio.input.fetch( + -- токен, полученный через audio.input.request_open + access_token: string, + -- максимальное размер буфера в байтах + [опционально] max_read_size: integer +) +``` + +### Пример генерации аудио: + +```lua +-- для работы с 16-битными семплами используйте U16view поверх Bytearray +-- пример: +local max_amplitude = 32767 +local sample_rate = 44100 +local total_samples = sample_rate * 5 -- 5 секунд моно +local bytes = Bytearray(total_samples * 2) -- 5 секунд 16 бит моно +local samples = I16view(bytes) + +local frequency_hz = 400 +for i=1, total_samples do + local value = math.sin(i * math.pi * 2 / sample_rate * frequency_hz) + samples[i] = value * max_amplitude +end + +local stream_name = "test-stream" +local stream = audio.PCMStream(sample_rate, 1, 16) +stream:feed(bytes) +stream:share(stream_name) + +local volume = 1.0 +local pitch = 1.0 +local channel = "ui" +audio.play_stream_2d(stream_name, volume, pitch, channel) +``` diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md index 19f1f8ab..c6c769ac 100644 --- a/doc/ru/scripting/ui.md +++ b/doc/ru/scripting/ui.md @@ -196,6 +196,10 @@ document["worlds-panel"]:clear() | data:update() | применяет изменения и загружает холст в видеопамять | | data:set_data(data: table) | заменяет данные пикселей (ширина * высота * 4 чисел) | | data:create_texture(name: str) | создаёт и делится текстурой с рендерером | +| data:unbind_texture() | отвязывает текстуру от холста | +| data:mul(*цвет* или Canvas) | умножает увет на указанный цвет или холст | +| data:add(*цвет* или Canvas) | прибавляет цвет или другой холст к цвету | +| data:sub(*цвет* или Canvas) | вычитает цвет или другой холст к цвету | ## Рамка встраивания (iframe) diff --git a/res/layouts/pages/settings_audio.xml.lua b/res/layouts/pages/settings_audio.xml.lua index 9b29bd52..29859819 100644 --- a/res/layouts/pages/settings_audio.xml.lua +++ b/res/layouts/pages/settings_audio.xml.lua @@ -24,10 +24,46 @@ 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("") + local prev_amplitude = 0.0 + document.tm:setInterval(16, function() + audio.input.fetch(token) + local amplitude = audio.input.get_max_amplitude() + if amplitude > 0.0 then + amplitude = math.sqrt(amplitude) + end + amplitude = math.max(amplitude, prev_amplitude - time.delta()) + document.input_volume_inner.size = { + prev_amplitude * + document.input_volume_outer.size[1], + document.input_volume_outer.size[2] + } + prev_amplitude = amplitude + 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("") + document.root:add("