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
	
	 James Ball
						James Ball