kopia lustrzana https://github.com/jameshball/osci-render
Lua support fully working and efficient except for sliders
rodzic
a4ee966f50
commit
91aa11ddcc
|
@ -300,7 +300,9 @@ void OscirenderAudioProcessor::updateFrame() {
|
|||
|
||||
frameLength = Shape::totalLength(frame);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DBG("frame not ready!");
|
||||
}
|
||||
}
|
||||
|
||||
void OscirenderAudioProcessor::updateLengthIncrement() {
|
||||
|
@ -345,7 +347,11 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
|
|||
double y = 0.0;
|
||||
double length = 0.0;
|
||||
|
||||
if (currentShape < frame.size()) {
|
||||
bool renderingSample = currentFile >= 0 && parsers[currentFile]->isSample();
|
||||
|
||||
if (renderingSample) {
|
||||
channels = parsers[currentFile]->nextSample();
|
||||
} else if (currentShape < frame.size()) {
|
||||
auto& shape = frame[currentShape];
|
||||
length = shape->length();
|
||||
double drawingProgress = length == 0.0 ? 1 : shapeDrawn / length;
|
||||
|
@ -360,6 +366,7 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
|
|||
|
||||
x = channels.x;
|
||||
y = channels.y;
|
||||
|
||||
|
||||
if (totalNumOutputChannels >= 2) {
|
||||
channelData[0][sample] = x;
|
||||
|
@ -368,29 +375,31 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
|
|||
channelData[0][sample] = x;
|
||||
}
|
||||
|
||||
// hard cap on how many times it can be over the length to
|
||||
// prevent audio stuttering
|
||||
frameDrawn += std::min(lengthIncrement, 20 * length);
|
||||
shapeDrawn += std::min(lengthIncrement, 20 * length);
|
||||
if (!renderingSample) {
|
||||
// hard cap on how many times it can be over the length to
|
||||
// prevent audio stuttering
|
||||
frameDrawn += std::min(lengthIncrement, 20 * length);
|
||||
shapeDrawn += std::min(lengthIncrement, 20 * length);
|
||||
|
||||
// Need to skip all shapes that the lengthIncrement draws over.
|
||||
// This is especially an issue when there are lots of small lines being
|
||||
// drawn.
|
||||
while (shapeDrawn > length) {
|
||||
shapeDrawn -= length;
|
||||
currentShape++;
|
||||
if (currentShape >= frame.size()) {
|
||||
currentShape = 0;
|
||||
break;
|
||||
}
|
||||
// POTENTIAL TODO: Think of a way to make this more efficient when iterating
|
||||
// this loop many times
|
||||
length = frame[currentShape]->len;
|
||||
}
|
||||
// Need to skip all shapes that the lengthIncrement draws over.
|
||||
// This is especially an issue when there are lots of small lines being
|
||||
// drawn.
|
||||
while (shapeDrawn > length) {
|
||||
shapeDrawn -= length;
|
||||
currentShape++;
|
||||
if (currentShape >= frame.size()) {
|
||||
currentShape = 0;
|
||||
break;
|
||||
}
|
||||
// POTENTIAL TODO: Think of a way to make this more efficient when iterating
|
||||
// this loop many times
|
||||
length = frame[currentShape]->len;
|
||||
}
|
||||
}
|
||||
|
||||
if (frameDrawn >= frameLength) {
|
||||
updateFrame();
|
||||
}
|
||||
if (!renderingSample && frameDrawn >= frameLength) {
|
||||
updateFrame();
|
||||
}
|
||||
}
|
||||
|
||||
juce::MidiBuffer processedMidi;
|
||||
|
|
|
@ -8,45 +8,61 @@ LuaParser::LuaParser(juce::String script) {
|
|||
luaL_openlibs(L);
|
||||
|
||||
this->script = script;
|
||||
parse();
|
||||
}
|
||||
|
||||
LuaParser::~LuaParser() {
|
||||
lua_close(L);
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Shape>> LuaParser::draw() {
|
||||
std::vector<std::unique_ptr<Shape>> shapes;
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
lua_pushnumber(L, step);
|
||||
lua_setglobal(L, "step");
|
||||
|
||||
const int ret = luaL_dostring(L, script.toUTF8());
|
||||
if (ret != 0) {
|
||||
const char* error = lua_tostring(L, -1);
|
||||
DBG(error);
|
||||
lua_pop(L, 1);
|
||||
} else if (lua_istable(L, -1)) {
|
||||
// get the first element of the table
|
||||
lua_pushinteger(L, 1);
|
||||
lua_gettable(L, -2);
|
||||
float x = (int)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// get the second element of the table
|
||||
lua_pushinteger(L, 2);
|
||||
lua_gettable(L, -2);
|
||||
float y = (int)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
shapes.push_back(std::make_unique<Vector2>(x, y));
|
||||
}
|
||||
|
||||
// pop the table
|
||||
lua_pop(L, 1);
|
||||
|
||||
step++;
|
||||
void LuaParser::parse() {
|
||||
const int ret = luaL_loadstring(L, script.toUTF8());
|
||||
if (ret != 0) {
|
||||
const char* error = lua_tostring(L, -1);
|
||||
DBG(error);
|
||||
lua_pop(L, 1);
|
||||
functionRef = -1;
|
||||
} else {
|
||||
functionRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
return shapes;
|
||||
}
|
||||
|
||||
Vector2 LuaParser::draw() {
|
||||
Vector2 sample;
|
||||
|
||||
if (functionRef == -1) {
|
||||
return sample;
|
||||
}
|
||||
|
||||
lua_pushnumber(L, step);
|
||||
lua_setglobal(L, "step");
|
||||
|
||||
lua_geti(L, LUA_REGISTRYINDEX, functionRef);
|
||||
|
||||
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||
if (ret != 0) {
|
||||
const char* error = lua_tostring(L, -1);
|
||||
DBG(error);
|
||||
functionRef = -1;
|
||||
} else if (lua_istable(L, -1)) {
|
||||
// get the first element of the table
|
||||
lua_pushinteger(L, 1);
|
||||
lua_gettable(L, -2);
|
||||
float x = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// get the second element of the table
|
||||
lua_pushinteger(L, 2);
|
||||
lua_gettable(L, -2);
|
||||
float y = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
sample = Vector2(x, y);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
||||
step++;
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@ public:
|
|||
LuaParser(juce::String script);
|
||||
~LuaParser();
|
||||
|
||||
std::vector<std::unique_ptr<Shape>> draw();
|
||||
Vector2 draw();
|
||||
private:
|
||||
void parse();
|
||||
int functionRef = -1;
|
||||
long step = 1;
|
||||
lua_State* L;
|
||||
juce::String script;
|
||||
|
|
|
@ -23,6 +23,8 @@ void FileParser::parse(juce::String extension, std::unique_ptr<juce::InputStream
|
|||
} else if (extension == ".lua") {
|
||||
lua = std::make_shared<LuaParser>(stream->readEntireStreamAsString());
|
||||
}
|
||||
|
||||
sampleSource = lua != nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
|
||||
|
@ -30,7 +32,6 @@ std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
|
|||
auto tempCamera = camera;
|
||||
auto tempSvg = svg;
|
||||
auto tempText = text;
|
||||
auto tempLua = lua;
|
||||
|
||||
if (tempObject != nullptr && tempCamera != nullptr) {
|
||||
return tempCamera->draw(*tempObject);
|
||||
|
@ -38,14 +39,23 @@ std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
|
|||
return tempSvg->draw();
|
||||
} else if (tempText != nullptr) {
|
||||
return tempText->draw();
|
||||
} else if (tempLua != nullptr) {
|
||||
return tempLua->draw();
|
||||
}
|
||||
auto tempShapes = std::vector<std::unique_ptr<Shape>>();
|
||||
tempShapes.push_back(std::make_unique<CircleArc>(0, 0, 0.5, 0.5, std::numbers::pi / 4.0, 2 * std::numbers::pi));
|
||||
return tempShapes;
|
||||
}
|
||||
|
||||
Vector2 FileParser::nextSample() {
|
||||
auto tempLua = lua;
|
||||
if (tempLua != nullptr) {
|
||||
return tempLua->draw();
|
||||
}
|
||||
}
|
||||
|
||||
bool FileParser::isSample() {
|
||||
return sampleSource;
|
||||
}
|
||||
|
||||
bool FileParser::isActive() {
|
||||
return active;
|
||||
}
|
||||
|
|
|
@ -14,12 +14,15 @@ public:
|
|||
|
||||
void parse(juce::String extension, std::unique_ptr<juce::InputStream>) override;
|
||||
std::vector<std::unique_ptr<Shape>> nextFrame() override;
|
||||
Vector2 nextSample() override;
|
||||
bool isSample() override;
|
||||
bool isActive() override;
|
||||
void disable() override;
|
||||
void enable() override;
|
||||
|
||||
private:
|
||||
bool active = true;
|
||||
bool sampleSource = false;
|
||||
|
||||
std::shared_ptr<WorldObject> object;
|
||||
std::shared_ptr<Camera> camera;
|
||||
|
|
|
@ -9,6 +9,8 @@ class FrameSource {
|
|||
public:
|
||||
virtual void parse(juce::String extension, std::unique_ptr<juce::InputStream>) = 0;
|
||||
virtual std::vector<std::unique_ptr<Shape>> nextFrame() = 0;
|
||||
virtual Vector2 nextSample() = 0;
|
||||
virtual bool isSample() = 0;
|
||||
virtual bool isActive() = 0;
|
||||
virtual void disable() = 0;
|
||||
virtual void enable() = 0;
|
||||
|
|
Ładowanie…
Reference in New Issue