Skip to content
Snippets Groups Projects
Commit 35e92cbf authored by jvoigts's avatar jvoigts
Browse files

initial commit julia plugin to dev branch

very early alpha  -  this still has a lot of hardcoded paths etc.!
parent f3397ad0
No related branches found
No related tags found
No related merge requests found
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "JuliaEditor.h"
#include "JuliaProcessor.h"
#include <stdio.h>
JuliaEditor::JuliaEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true)
: GenericEditor(parentNode, useDefaultParameterEditors)
{
juliaProcessor = (JuliaProcessor*) parentNode;
lastFilePath = File::getCurrentWorkingDirectory();
fileButton = new UtilityButton("Select file",Font("Small Text", 13, Font::plain));
fileButton->addListener(this);
fileButton->setBounds(10,85,100,25);
addAndMakeVisible(fileButton);
reloadFileButton = new UtilityButton("refresh",Font("Small Text", 13, Font::plain));
reloadFileButton->addListener(this);
reloadFileButton->setBounds(100+10,85,60,25);
addAndMakeVisible(reloadFileButton);
fileNameLabel = new Label("FileNameLabel", "No file selected.");
fileNameLabel->setBounds(10,85+20,140,25);
addAndMakeVisible(fileNameLabel);
bufferSizeSelection = new Label("Buffer Size","30000"); // this is currently set in RHD2000Thread, the cleaner would be to set it here again
bufferSizeSelection->setEditable(true,false,false);
bufferSizeSelection->addListener(this);
bufferSizeSelection->setBounds(120,60,60,20);
bufferSizeSelection->setColour(Label::textColourId, Colours::darkgrey);
addAndMakeVisible(bufferSizeSelection);
bufferSizeSelectionLabel = new Label("","NBuf.:");
bufferSizeSelectionLabel->attachToComponent (bufferSizeSelection,true);
addAndMakeVisible(bufferSizeSelectionLabel);
// Image im;
// im = ImageCache::getFromMemory(BinaryData::JuliaIconActive_png,
// BinaryData::JuliaIconActive_pngSize);
// icon = new ImageIcon(im);
// addAndMakeVisible(icon);
// icon->setBounds(15,25,61,54);
// icon->setOpacity(0.3f);
desiredWidth = 200;
setEnabledState(false);
}
JuliaEditor::~JuliaEditor()
{
}
void JuliaEditor::setFile(String file)
{
File fileToRead(file);
lastFilePath = fileToRead.getParentDirectory();
juliaProcessor->setFile(fileToRead.getFullPathName());
fileNameLabel->setText(fileToRead.getFileName(), dontSendNotification);
// setEnabledState(true);
// icon->setOpacity(1.0f); // tie this to hasJuliaInstance instead of just setting it!
// repaint();
}
void JuliaEditor::buttonEvent(Button* button)
{
if (!acquisitionIsActive)
{
if (button == fileButton)
{
//std::cout << "Button clicked." << std::endl;
//FileChooser chooseJuliaProcessorFile("Please select the file you want to load...", lastFilePath, "*");
// file dialogs are screwed up in current xubuntu, so we'll do this for now.
setFile("/home/jvoigts/Documents/Github/plugin-GUI/Source/Plugins/JuliaProcessor/exampleProcessor.jl");
// if (chooseJuliaProcessorFile.browseForFileToOpen())
{
// Use the selected file
//setFile(chooseJuliaProcessorFile.getResult().getFullPathName());
// lastFilePath = fileToRead.getParentDirectory();
// thread->setFile(fileToRead.getFullPathName());
// fileNameLabel->setText(fileToRead.getFileName(),false);
}
}
if (button == reloadFileButton)
{
juliaProcessor->reloadFile();
}
}
}
void JuliaEditor::labelTextChanged(Label* label)
{
if (!acquisitionIsActive)
{
if (label == bufferSizeSelection)
{
Value val = label->getTextValue();
juliaProcessor->setBuffersize(int(val.getValue()));
}
}
}
void JuliaEditor::saveEditorParameters(XmlElement* xml)
{
// XmlElement* fileName = xml->createNewChildElement("FILENAME");
// fileName->addTextElement(lastFilePath.getFullPathName());
}
void JuliaEditor::loadEditorParameters(XmlElement* xml)
{
// forEachXmlChildElement(*xml, xmlNode)
// {
// if (xmlNode->hasTagName("FILENAME"))
// {
// lastFilePath = File(xmlNode->getText());
// thread->setFile(lastFilePath.getFullPathName());
// fileNameLabel->setText(lastFilePath.getFullPathName(),false);
// }
// }
}
\ No newline at end of file
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JULIAEDITOR_H_INCLUDED
#define JULIAEDITOR_H_INCLUDED
#include <EditorHeaders.h>
//class ImageIcon;
class JuliaProcessor;
/**
User interface for the Julia processor.
@see JuliaProcessor
*/
class JuliaEditor : public GenericEditor, public Label::Listener
{
public:
JuliaEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors);
virtual ~JuliaEditor();
void buttonEvent(Button* button);
void labelTextChanged(Label* te);
void setFile(String file);
void saveEditorParameters(XmlElement*);
void loadEditorParameters(XmlElement*);
ImageIcon* icon;
private:
ScopedPointer<UtilityButton> fileButton;
ScopedPointer<UtilityButton> reloadFileButton;
ScopedPointer<Label> fileNameLabel;
ScopedPointer<Label> bufferSizeSelection;
ScopedPointer<Label> bufferSizeSelectionLabel;
JuliaProcessor* juliaProcessor;
File lastFilePath;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JuliaEditor);
};
#endif // JULIAEDITOR_H_INCLUDED
\ No newline at end of file
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "JuliaProcessor.h"
#include "JuliaEditor.h"
#include <stdio.h>
#include <julia.h>
JuliaProcessor::JuliaProcessor()
: GenericProcessor("Julia Processor")
{
hasJuliaInstance = false;
dataHistoryBufferNumChannels = 256;
dataHistoryBuffer = new AudioSampleBuffer(dataHistoryBufferNumChannels, 60000);
dataHistoryBuffer->clear();
}
JuliaProcessor::~JuliaProcessor()
{
jl_atexit_hook(0);
deleteAndZero(dataHistoryBuffer);
}
AudioProcessorEditor* JuliaProcessor::createEditor()
{
editor = new JuliaEditor(this, true);
std::cout << "Creating Julia editor." << std::endl;
return editor;
}
void JuliaProcessor::setFile(String fullpath)
{
hasJuliaInstance = true;
filePath = fullpath;
FILE* fp = popen("echo $JULIA", "r");
char input[255];
fgets(input, sizeof(input), fp);
String julia_bin_dir = input;
julia_bin_dir = julia_bin_dir.trimEnd();
julia_bin_dir += "/home/jvoigts/Documents/Github/julia/usr/bin";
String julia_sys_dir = input;
julia_sys_dir = julia_sys_dir.trimEnd();
julia_sys_dir += "/home/jvoigts/Documents/Github/julia/usr/lib/julia/sys.so";
const char* jbin = julia_bin_dir.toRawUTF8();
const char* jsys = julia_sys_dir.toRawUTF8();
jl_init_with_image(jbin, jsys);
String juliaString = "include(\"" + filePath + "\")";
run_julia_string(juliaString);
}
void JuliaProcessor::reloadFile()
{
if (hasJuliaInstance)
{
String juliaString = "reload(\"" + filePath + "\")";
run_julia_string(juliaString);
}
else
{
std::cout << "No julia instance running - cant refresh" << std::endl;
}
}
void JuliaProcessor::setParameter(int parameterIndex, float newValue)
{
editor->updateParameterButtons(parameterIndex);
}
void JuliaProcessor::setBuffersize(int bufferSize)
{
if (bufferSize > 1)
{
dataHistoryBufferSize=bufferSize;
printf("Setting history buffer size to %d samples \n", dataHistoryBufferSize);
dataHistoryBuffer->setSize(dataHistoryBufferNumChannels, dataHistoryBufferSize, false, true, false);
}
else
{
printf("History buffer size has to be at least 1");
}
}
void JuliaProcessor::run_julia_string(String juliaString)
{
// need to convert from juce String to char array
const char* jstr = juliaString.toRawUTF8();
printf("executing julia cmd: %s\n", jstr);
jl_eval_string(jstr);
if (jl_exception_occurred())
printf("%s \n", jl_typeof_str(jl_exception_occurred()));
}
String JuliaProcessor::getFile()
{
return filePath;
}
void JuliaProcessor::process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
if (hasJuliaInstance)
{
jl_function_t *func = jl_get_function(jl_main_module, "oe_process!");
// create 2D array of float64 type
jl_value_t *array_type = jl_apply_array_type(jl_float32_type, 1); // last arg is nDims
for (int n = 0; n < getNumOutputs(); n++)
{
float* ptr = buffer.getWritePointer(n); // to perform in-place edits to the buffer
jl_array_t *x = jl_ptr_to_array_1d(array_type, ptr , buffer.getNumSamples(), 0);
JL_GC_PUSH1(&x);
jl_call1(func, (jl_value_t*)x);
JL_GC_POP();
}
}
}
void JuliaProcessor::saveCustomParametersToXml(XmlElement* parentElement)
{
XmlElement* childNode = parentElement->createNewChildElement("FILENAME");
childNode->setAttribute("path", getFile());
}
void JuliaProcessor::loadCustomParametersFromXml()
{
if (parametersAsXml != nullptr)
{
// use parametersAsXml to restore state
forEachXmlChildElement(*parametersAsXml, xmlNode)
{
if (xmlNode->hasTagName("FILENAME"))
{
String filepath = xmlNode->getStringAttribute("path");
JuliaEditor* fre = (JuliaEditor*) getEditor();
fre->setFile(filepath);
}
}
}
}
\ No newline at end of file
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JULIAPROCESSOR_H_INCLUDED
#define JULIAPROCESSOR_H_INCLUDED
#include <ProcessorHeaders.h>
/**
Julia Processor.
Allows the user to select a Julia Programming Language file to use as filter
@see GenericProcessor, JuliaEditor
*/
class JuliaProcessor : public GenericProcessor
{
public:
JuliaProcessor();
~JuliaProcessor();
void setFile(String fullpath);
String getFile();
void reloadFile();
void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
void setParameter(int parameterIndex, float newValue);
void setBuffersize(int bufferSize);
AudioProcessorEditor* createEditor();
bool hasEditor() const
{
return true;
}
void saveCustomParametersToXml(XmlElement* parentElement);
void loadCustomParametersFromXml();
private:
bool hasJuliaInstance;
String filePath;
int dataHistoryBufferSize;
int dataHistoryBufferNumChannels;
AudioSampleBuffer* dataHistoryBuffer;
void run_julia_string(String juliaString);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JuliaProcessor);
};
#endif // JULIAPROCESSOR_H_INCLUDED
LIBNAME := $(notdir $(CURDIR))
OBJDIR := $(OBJDIR)/$(LIBNAME)
TARGET := $(LIBNAME).so
SRC_DIR := ${shell find ./ -type d -print}
VPATH := $(SOURCE_DIRS)
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp))
OBJ := $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o)))
JULIA = /home/jvoigts/Documents/Github/julia/
# flags to compile "JuliaProcessor". $(JULIA): toplevel of julia package
CXXFLAGS += -I $(JULIA)/src -I $(JULIA)/src/support -I $(JULIA)/usr/include
LDFLAGS += -L $(JULIA)/usr/lib -Wl,-R $(JULIA)/usr/lib -ljulia
BLDCMD := $(CXX) -shared -o $(OUTDIR)/$(TARGET) $(OBJ) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)
VPATH = $(SRC_DIR)
.PHONY: objdir
$(OUTDIR)/$(TARGET): objdir $(OBJ)
-@mkdir -p $(BINDIR)
-@mkdir -p $(LIBDIR)
-@mkdir -p $(OUTDIR)
@echo "Building $(TARGET)"
@$(BLDCMD)
$(OBJDIR)/%.o : %.cpp
@echo "Compiling $<"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
objdir:
-@mkdir -p $(OBJDIR)
clean:
@echo "Cleaning $(LIBNAME)"
-@rm -rf $(OBJDIR)
-@rm -f $(OUTDIR)/$(TARGET)
-include $(OBJ:%.o=%.d)
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <PluginInfo.h>
#include "JuliaProcessor.h"
#include <string>
#ifdef WIN32
#include <Windows.h>
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
using namespace Plugin;
#define NUM_PLUGINS 1
extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info)
{
info->apiVersion = PLUGIN_API_VER;
info->name = "Julia Processor";
info->libVersion = 1;
info->numPlugins = NUM_PLUGINS;
}
extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
{
switch (index)
{
case 0:
info->type = Plugin::ProcessorPlugin;
info->processor.name = "Julia Processor";
info->processor.type = Plugin::FilterProcessor;
info->processor.creator = &(Plugin::createProcessor<JuliaProcessor>);
break;
default:
return -1;
break;
}
return 0;
}
#ifdef WIN32
BOOL WINAPI DllMain(IN HINSTANCE hDllHandle,
IN DWORD nReason,
IN LPVOID Reserved)
{
return TRUE;
}
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment