add test PCMStream lua use

This commit is contained in:
MihailRis 2025-10-14 00:51:04 +03:00
parent 31137f83b6
commit 84f087049d
6 changed files with 157 additions and 0 deletions

View File

@ -116,6 +116,17 @@ function on_hud_open()
configure_SSAO()
hud.default_hand_controller = update_hand
local stream = PCMStream(44100, 1, 8)
stream:share("test-stream")
local bytes = Bytearray(44100 * 16)
for i=1,#bytes do
local x = math.sin(i * 0.08) * 127 + 128
bytes[i] = x
end
stream:feed(bytes)
audio.play_stream_2d("test-stream", 0.05, 1.0)
end
function on_hud_render()

View File

@ -121,6 +121,10 @@ namespace audio {
/// (always equals bufferSize if seekable and looped)
virtual size_t readFully(char* buffer, size_t bufferSize, bool loop);
/// @brief Read available data to buffer
/// @param buffer destination buffer
/// @param bufferSize destination buffer size
/// @return count of received bytes or PCMStream::ERROR
virtual size_t read(char* buffer, size_t bufferSize) = 0;
/// @brief Close stream

View File

@ -67,6 +67,26 @@ inline audio::speakerid_t play_stream(
if (channel == -1) {
return 0;
}
if (!scripting::engine->isHeadless()) {
auto assets = scripting::engine->getAssets();
auto stream = assets->getShared<audio::PCMStream>(filename);
if (stream) {
return audio::play(
audio::open_stream(std::move(stream), true),
glm::vec3(
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z)
),
relative,
volume,
pitch,
loop,
channel
);
}
}
io::path file;
if (std::strchr(filename, ':')) {
file = std::string(filename);

View File

@ -12,6 +12,7 @@
#include "usertypes/lua_type_voxelfragment.hpp"
#include "usertypes/lua_type_canvas.hpp"
#include "usertypes/lua_type_random.hpp"
#include "usertypes/lua_type_pcmstream.hpp"
#include "engine/Engine.hpp"
static debug::Logger logger("lua-state");
@ -130,6 +131,7 @@ void lua::init_state(State* L, StateType stateType) {
newusertype<LuaHeightmap>(L);
newusertype<LuaVoxelFragment>(L);
newusertype<LuaCanvas>(L);
newusertype<LuaPCMStream>(L);
}
void lua::initialize(const EnginePaths& paths, const CoreParameters& params) {

View File

@ -0,0 +1,94 @@
#include "../lua_util.hpp"
#include "lua_type_pcmstream.hpp"
#include "assets/Assets.hpp"
#include "audio/MemoryPCMStream.hpp"
#include "engine/Engine.hpp"
using namespace lua;
using namespace audio;
using namespace scripting;
LuaPCMStream::LuaPCMStream(std::shared_ptr<audio::MemoryPCMStream>&& stream)
: stream(std::move(stream)) {
}
LuaPCMStream::~LuaPCMStream() = default;
const std::shared_ptr<audio::MemoryPCMStream>& LuaPCMStream::getStream() const {
return stream;
}
#include <iostream>
static int l_feed(lua::State* L) {
std::cout << "feed" << std::endl;
auto stream = touserdata<LuaPCMStream>(L, 1);
if (stream == nullptr) {
return 0;
}
auto bytes = bytearray_as_string(L, 2);
stream->getStream()->feed(
{reinterpret_cast<const ubyte*>(bytes.data()), bytes.size()}
);
return 0;
}
static int l_share(lua::State* L) {
auto stream = touserdata<LuaPCMStream>(L, 1);
if (stream == nullptr) {
return 0;
}
auto alias = require_lstring(L, 2);
if (engine->isHeadless()) {
return 0;
}
auto assets = engine->getAssets();
assets->store<PCMStream>(stream->getStream(), std::string(alias));
return 0;
}
static std::unordered_map<std::string, lua_CFunction> methods {
{"feed", lua::wrap<l_feed>},
{"share", lua::wrap<l_share>},
};
static int l_meta_meta_call(lua::State* L) {
auto sampleRate = touinteger(L, 2);
auto channels = touinteger(L, 3);
auto bitsPerSample = touinteger(L, 4);
auto stream =
std::make_shared<MemoryPCMStream>(sampleRate, channels, bitsPerSample);
return newuserdata<LuaPCMStream>(L, std::move(stream));
}
static int l_meta_tostring(lua::State* L) {
return pushstring(L, "PCMStream");
}
static int l_meta_index(lua::State* L) {
auto stream = touserdata<LuaPCMStream>(L, 1);
if (stream == nullptr) {
return 0;
}
if (isstring(L, 2)) {
auto found = methods.find(tostring(L, 2));
if (found != methods.end()) {
return pushcfunction(L, found->second);
}
}
return 0;
}
int LuaPCMStream::createMetatable(lua::State* L) {
createtable(L, 0, 3);
pushcfunction(L, lua::wrap<l_meta_tostring>);
setfield(L, "__tostring");
pushcfunction(L, lua::wrap<l_meta_index>);
setfield(L, "__index");
createtable(L, 0, 1);
pushcfunction(L, lua::wrap<l_meta_meta_call>);
setfield(L, "__call");
setmetatable(L);
return 1;
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "../lua_commons.hpp"
namespace audio {
class MemoryPCMStream;
}
namespace lua {
class LuaPCMStream : public Userdata {
public:
explicit LuaPCMStream(std::shared_ptr<audio::MemoryPCMStream>&& stream);
virtual ~LuaPCMStream() override;
const std::shared_ptr<audio::MemoryPCMStream>& getStream() const;
const std::string& getTypeName() const override {
return TYPENAME;
}
static int createMetatable(lua::State*);
inline static std::string TYPENAME = "PCMStream";
private:
std::shared_ptr<audio::MemoryPCMStream> stream;
};
static_assert(!std::is_abstract<LuaPCMStream>());
}