Added first files
This commit is contained in:
parent
807fb891b9
commit
3c7a0a7a7c
12 changed files with 12233 additions and 0 deletions
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[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
|
||||||
114
SConstruct
Normal file
114
SConstruct
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
#!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))
|
||||||
9
bin/gdpd.gdns
Normal file
9
bin/gdpd.gdns
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[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" ]
|
||||||
18
bin/libgdpd.gdnlib
Normal file
18
bin/libgdpd.gdnlib
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
[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=[ ]
|
||||||
16
src/gdlibrary.cpp
Normal file
16
src/gdlibrary.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#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>();
|
||||||
|
}
|
||||||
|
|
||||||
170
src/gdpd.cpp
Normal file
170
src/gdpd.cpp
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
#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);
|
||||||
|
}
|
||||||
59
src/gdpd.hpp
Normal file
59
src/gdpd.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#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
|
||||||
1
src/godot-cpp
Submodule
1
src/godot-cpp
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3ee07f652bbbe91630a8346e3fe39a05f0f1d76a
|
||||||
1
src/libpd
Submodule
1
src/libpd
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit e07d211d7b7e5f8dd6d2e3ddce557ae453161a14
|
||||||
10636
src/rtaudio/RtAudio.cpp
Normal file
10636
src/rtaudio/RtAudio.cpp
Normal file
File diff suppressed because it is too large
Load diff
1203
src/rtaudio/RtAudio.h
Normal file
1203
src/rtaudio/RtAudio.h
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/rtaudio/RtAudio.os
Normal file
BIN
src/rtaudio/RtAudio.os
Normal file
Binary file not shown.
Loading…
Reference in a new issue