Commit 3c7a0a7a authored by BERTHAUT Florent's avatar BERTHAUT Florent
Browse files

Added first files

parent 807fb891
[submodule "src/libpd"]
path = src/libpd
url = https://github.com/libpd/libpd.git
[submodule "src/godot-cpp"]
path = src/godot-cpp
url = https://github.com/GodotNativeTools/godot-cpp
#!python
import os, subprocess
opts = Variables([], ARGUMENTS)
# Gets the standard flags CC, CCX, etc.
env = DefaultEnvironment()
# Define our options
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release']))
opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", '', ['', 'windows', 'x11', 'linux', 'osx']))
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/'))
opts.Add(PathVariable('target_name', 'The library name.', 'libgdpd', PathVariable.PathAccept))
# Local dependency paths, adapt them to your setup
godot_headers_path = "src/godot-cpp/godot_headers/"
cpp_bindings_path = "src/godot-cpp/"
cpp_library = "libgodot-cpp"
# only support 64 at this time..
bits = 64
# Updates the environment with the option variables.
opts.Update(env)
# Process some arguments
if env['use_llvm']:
env['CC'] = 'clang'
env['CXX'] = 'clang++'
if env['p'] != '':
env['platform'] = env['p']
if env['platform'] == '':
print("No valid target platform selected.")
quit();
# For the reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
# Check our platform specifics
if env['platform'] == "osx":
env['target_path'] += 'osx/'
cpp_library += '.osx'
if env['target'] in ('debug', 'd'):
env.Append(CCFLAGS=['-g', '-O2', '-arch', 'x86_64'])
env.Append(LINKFLAGS=['-arch', 'x86_64'])
else:
env.Append(CCFLAGS=['-g', '-O3', '-arch', 'x86_64'])
env.Append(LINKFLAGS=['-arch', 'x86_64'])
elif env['platform'] in ('x11', 'linux'):
env['target_path'] += 'x11/'
cpp_library += '.linux'
env.Append(CPPDEFINES=['__UNIX_JACK__'])
env.Append(LINKFLAGS=['-ljack','-pthread'])
if env['target'] in ('debug', 'd'):
env.Append(CCFLAGS=['-fPIC', '-g3', '-Og'])
env.Append(CFLAGS=['-std=c11'])
env.Append(CXXFLAGS=['-std=c++17'])
else:
env.Append(CCFLAGS=['-fPIC', '-g', '-O3'])
env.Append(CFLAGS=['-std=c11'])
env.Append(CXXFLAGS=['-std=c++17'])
elif env['platform'] == "windows":
env['target_path'] += 'win64/'
cpp_library += '.windows'
# This makes sure to keep the session environment variables on windows,
# that way you can run scons in a vs 2017 prompt and it will find all the required tools
env.Append(ENV=os.environ)
env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
env.Append(CCFLAGS=['-W3', '-GR'])
if env['target'] in ('debug', 'd'):
env.Append(CPPDEFINES=['_DEBUG'])
env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI'])
env.Append(LINKFLAGS=['-DEBUG'])
else:
env.Append(CPPDEFINES=['NDEBUG'])
env.Append(CCFLAGS=['-O2', '-EHsc', '-MD'])
if env['target'] in ('debug', 'd'):
cpp_library += '.debug'
else:
cpp_library += '.release'
cpp_library += '.' + str(bits)
# make sure our binding library is properly includes
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', 'src/libpd/cpp','src/libpd/pure-data/src', 'src/libpd/libpd_wrapper', 'src/libpd/libpd_wrapper/util', 'src/rtaudio'])
env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
env.Append(LIBS=[cpp_library])
env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=['src/'])
#sources = Glob('src/*.cpp')
sources = Glob('src/*.cpp') + Glob('src/rtaudio/*.cpp') + Glob('src/libpd/libpd_wrapper/*.c') + Glob('src/libpd/libpd_wrapper/util/*.c') + Glob('src/libpd/pure-data/extra/**/*.c') + Glob('src/libpd/pure-data/src/[xmgz]_*.c') + Glob('src/libpd/pure-data/src/d_[acgmorsu]*.c') + Glob('src/libpd/pure-data/src/d_dac.c') + Glob('src/libpd/pure-data/src/d_delay.c') + Glob('src/libpd/pure-data/src/d_fft.c') + Glob('src/libpd/pure-data/src/d_fft_fftsg.c') + Glob('src/libpd/pure-data/src/d_filter.c') + Glob('src/libpd/pure-data/src/s_audio.c') + Glob('src/libpd/pure-data/src/s_audio_dummy.c') + Glob('src/libpd/pure-data/src/s_print.c') + Glob('src/libpd/pure-data/src/s_path.c') + Glob('src/libpd/pure-data/src/s_main.c') + Glob('src/libpd/pure-data/src/s_inter.c') + Glob('src/libpd/pure-data/src/s_utf8.c') + Glob('src/libpd/pure-data/src/s_loader.c')
library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
Default(library)
# Generates help for the -h scons option.
Help(opts.GenerateHelpText(env))
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://addons/gdpd/bin/libgdpd.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "gdpd"
class_name = "Gdpd"
library = ExtResource( 1 )
_sections_unfolded = [ "Resource" ]
[general]
singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=true
[entry]
X11.64="res://addons/gdpd/bin/x11/libgdpd.so"
Windows.64="res://addons/gdpd/bin/win/libgdpd.dll"
OSX.64="res://addons/gdpd/bin/osx/libgdpd.dylib"
[dependencies]
X11.64=[]
Windows.64=[ ]
OSX.64=[ ]
#include "gdpd.hpp"
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
godot::Godot::gdnative_init(o);
}
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
godot::Godot::gdnative_terminate(o);
}
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
godot::Godot::nativescript_init(handle);
godot::register_class<godot::Gdpd>();
}
#include "gdpd.hpp"
using namespace godot;
void Gdpd::_register_methods() {
register_method("init", &Gdpd::init);
register_method("openfile", &Gdpd::openfile);
register_method("closefile", &Gdpd::closefile);
register_method("has_message", &Gdpd::has_message);
register_method("get_next", &Gdpd::get_next);
register_method("start_message", &Gdpd::start_message);
register_method("add_symbol", &Gdpd::add_symbol);
register_method("add_float", &Gdpd::add_float);
register_method("finish_list", &Gdpd::finish_list);
}
int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData){
// pass audio samples to/from libpd
int ticks = nBufferFrames / 64;
libpd_process_float(ticks, (float*)inputBuffer, (float*)outputBuffer);
return 0;
}
Gdpd::Gdpd() {
}
void Gdpd::_init() {
}
Gdpd::~Gdpd() {
// add your cleanup here
}
int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate) {
if(!m_pd.init(nbInputs, nbOutputs, sampleRate, true)) {
Godot::print("GDPD : Error starting libpd");
return 1;
}
/*
int bufsize = 128;
m_inBuf = new float[bufsize * nbInputs];
m_outBuf = new float[bufsize * nbOutputs];
*/
//create message array
m_messages = new Array();
//create message hook
m_pd.subscribe("to_gdpd");
m_pd.setReceiver(this);
//start dsp
m_pd.computeAudio(true);
//intialize rtaudio
if(m_audio.getDeviceCount()==0){
Godot::print("There are no available sound devices.");
}
RtAudio::StreamParameters outParams, inParams;
unsigned int sr = m_audio.getDeviceInfo(outParams.deviceId).preferredSampleRate;
outParams.deviceId = m_audio.getDefaultOutputDevice();
inParams.deviceId = m_audio.getDefaultOutputDevice();
outParams.nChannels = nbInputs;
inParams.nChannels = nbOutputs;
m_bufferFrames = 128;
RtAudio::StreamOptions options;
options.streamName = "gdpd";
options.flags = RTAUDIO_SCHEDULE_REALTIME;
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
options.flags |= RTAUDIO_MINIMIZE_LATENCY; // CoreAudio doesn't seem to like this
}
try {
m_audio.openStream(&outParams, &inParams, RTAUDIO_FLOAT32,
sr, &m_bufferFrames, &audioCallback,
&m_pd, &options);
m_audio.startStream();
}
catch(RtAudioError& e) {
Godot::print(e.getMessage().c_str());
}
Godot::print("GDPD : Initialized");
return 0;
}
void Gdpd::openfile(godot::String baseStr, godot::String dirStr) {
std::wstring baseWs = baseStr.unicode_str();
std::string baseS(baseWs.begin(), baseWs.end());
std::wstring dirWs = dirStr.unicode_str();
std::string dirS(dirWs.begin(), dirWs.end());
libpd_openfile(baseS.c_str(), dirS.c_str());
Godot::print("GDPD : Opened patch");
}
void Gdpd::closefile() {
m_pd.closePatch(m_patch);
}
bool Gdpd::has_message() {
//receive new messages
m_pd.receiveMessages();
//return if more than one message
int size = m_messages->size();
return size>0;
}
Array Gdpd::get_next() {
Array msg = m_messages->pop_front();
return msg;
}
int Gdpd::blocksize() {
int blocksize = libpd_blocksize();
return blocksize;
}
int Gdpd::start_message(int nbValues) {
int res = libpd_start_message(nbValues);
return res;
}
void Gdpd::add_symbol(String symbStr) {
std::wstring symbWs = symbStr.unicode_str();
std::string symbS(symbWs.begin(), symbWs.end());
libpd_add_symbol(symbS.c_str());
}
void Gdpd::add_float(float val) {
libpd_add_float(val);
}
int Gdpd::finish_list(String destStr) {
std::wstring destWs = destStr.unicode_str();
std::string destS(destWs.begin(), destWs.end());
int res = libpd_finish_list(destS.c_str());
return res;
}
void Gdpd::print(const std::string& message) {
Godot::print(message.c_str());
}
void Gdpd::receiveList(const std::string& dest, const pd::List& list) {
Array gdlist;
for(int i = 0; i < list.len(); ++i) {
if(list.isFloat(i)) {
gdlist.push_back(list.getFloat(i));
}
else if(list.isSymbol(i)) {
String symbStr(list.getSymbol(i).c_str());
gdlist.push_back(symbStr);
}
}
m_messages->push_back(gdlist);
}
#ifndef GDPD_H
#define GDPD_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Godot.hpp>
#include <AudioStreamPlayer.hpp>
#include "PdBase.hpp"
#include "PdReceiver.hpp"
#include "RtAudio.h"
namespace godot {
class Gdpd : public godot::AudioStreamPlayer, public pd::PdReceiver {
GODOT_CLASS(Gdpd, AudioStreamPlayer)
private:
float *m_inBuf;
float *m_outBuf;
Array* m_messages;
pd::PdBase m_pd;
pd::Patch m_patch;
RtAudio m_audio;
unsigned int m_bufferFrames;
public:
static void _register_methods();
Gdpd();
~Gdpd();
void _init();
//libpd functions
int init(int nbInputs, int nbOutputs, int sampleRate);
void openfile(String basename, String dirname);
void closefile();
bool has_message();
Array get_next();
int blocksize();
int start_message(int nbValues);
void add_symbol(String symbStr);
void add_float(float val);
int finish_list(String destStr);
//libpd hooks
void print(const std::string& message);
void receiveList(const std::string& dest, const pd::List& list);
static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData);
};
}
#endif
Subproject commit 3ee07f652bbbe91630a8346e3fe39a05f0f1d76a
Subproject commit e07d211d7b7e5f8dd6d2e3ddce557ae453161a14
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment