commit a4ecf324794fc55370f43570fdc5aac29d07ee6d
parent 368e544ca923fcf0246639564070adb07e2f145c
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Thu, 7 Feb 2013 13:10:30 -0500
Minimum librtosc integration
- It's quick, ugly, and spawns more issues than it solves, but it must begin
somewhere
- Master::volume is now controllable via OSC
Diffstat:
5 files changed, 168 insertions(+), 6 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -113,22 +113,22 @@ option (BuildForDebug "Include gdb debugging support" OFF)
set(CMAKE_BUILD_TYPE "Release")
set (BuildOptions_x86_64AMD
- "-O3 -march=athlon64 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
+ "-std=c++0x -O3 -march=athlon64 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
CACHE STRING "X86_64 compiler options"
)
set (BuildOptions_X86_64Core2
- "-O3 -march=core2 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
+ "-std=c++0x -O3 -march=core2 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
CACHE STRING "X86_64 compiler options"
)
set (BuildOptionsBasic
- "-O3 -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer"
+ "-std=c++0x -O3 -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer"
CACHE STRING "basic X86 complier options"
)
set (BuildOptionsDebug
- "-O0 -g3 -ggdb -Wall -Wpointer-arith" CACHE STRING "Debug build flags")
+ "-std=c++0x -O0 -g3 -ggdb -Wall -Wpointer-arith" CACHE STRING "Debug build flags")
########### Settings dependant code ###########
# From here on, the setting variables have been prepared so concentrate
@@ -321,7 +321,8 @@ target_link_libraries(zynaddsubfx_core
${FFTW_LIBRARIES}
${MXML_LIBRARIES}
${OS_LIBRARIES}
- pthread)
+ pthread
+ rtosc)
message(STATUS "using link directories: ${AUDIO_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${FFTW_LIBRARY_DIRS} ${MXML_LIBRARY_DIRS} ${FLTK_LIBRARY_DIRS}")
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -29,6 +29,8 @@
#include "../Effects/EffectMgr.h"
#include "../DSP/FFTwrapper.h"
+#include <rtosc/ports.h>
+#include <rtosc/thread-link.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -39,6 +41,31 @@
#include <unistd.h>
using namespace std;
+using rtosc::Ports;
+using rtosc::RtData;
+
+template<class T>
+T lim(T min, T max, T val)
+{
+ return val<max?(val>min?val:min):max;
+}
+//floating point parameter - with lookup code
+#define PARAMF(type, var, name, scale, _min, _max, desc) \
+{#name"::f", #scale "," # _min "," #_max ":'parameter':" desc, 0, \
+ [](const char *m, RtData d) { \
+ if(rtosc_narguments(m)==0) {\
+ bToU->write("/display", "sf", d.loc, ((type*)d.obj)->var); \
+ } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='f') {\
+ ((type*)d.obj)->var = lim<float>(_min,_max,rtosc_argument(m,0).f); \
+ bToU->write(d.loc, "f", ((type*)d.obj)->var);}}}
+
+static Ports localports = {
+ {"echo", ":'hidden':Hidden port to echo messages", 0, [](const char *m, RtData) {
+ bToU->raw_write(m-1);}},
+ PARAMF(Master, volume, volume, log, 0.01, 4.42, "Master Volume"),
+};
+
+Ports &Master::ports = localports;
vuData::vuData(void)
:outpeakl(0.0f), outpeakr(0.0f), maxoutpeakl(0.0f), maxoutpeakr(0.0f),
@@ -319,6 +346,11 @@ void Master::partonoff(int npart, int what)
*/
void Master::AudioOut(float *outl, float *outr)
{
+ //Handle user events TODO move me to a proper location
+ char loc_buf[1024];
+ while(uToB->hasNext())
+ ports.dispatch(loc_buf, 1024, uToB->read()+1, this);
+
//Swaps the Left channel with Right Channel
if(swaplr)
swap(outl, outr);
diff --git a/src/Misc/Master.h b/src/Misc/Master.h
@@ -164,10 +164,11 @@ class Master
pthread_mutex_t vumutex;
+ static rtosc::Ports &ports;
+ float volume;
private:
bool nullRun;
vuData vu;
- float volume;
float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
int keyshift;
diff --git a/src/globals.h b/src/globals.h
@@ -26,6 +26,10 @@
#define GLOBALS_H
#include <stdint.h>
+//Forward declarations
+namespace rtosc{class Ports; class ThreadLink;};
+extern rtosc::ThreadLink *bToU;
+extern rtosc::ThreadLink *uToB;
/**
* The number of harmonics of additive synth
diff --git a/src/main.cpp b/src/main.cpp
@@ -35,6 +35,10 @@
#include <getopt.h>
+#include <lo/lo.h>
+#include <rtosc/ports.h>
+#include <rtosc/thread-link.h>
+
#include "DSP/FFTwrapper.h"
#include "Misc/Master.h"
#include "Misc/Part.h"
@@ -96,6 +100,122 @@ void sigterm_exit(int /*sig*/)
Pexitprogram = 1;
}
+void error_cb(int i, const char *m, const char *loc)
+{
+ fprintf(stderr, "liblo :-( %d-%s@%s\n",i,m,loc);
+}
+
+lo_server server;
+rtosc::ThreadLink *bToU = new rtosc::ThreadLink(1024,1024);
+rtosc::ThreadLink *uToB = new rtosc::ThreadLink(1024,1024);
+string last_url, curr_url;
+
+void path_search(const char *m)
+{
+ using rtosc::Ports;
+ using rtosc::Port;
+
+ //assumed upper bound of 32 ports (may need to be resized)
+ char types[65];
+ rtosc_arg_t args[64];
+ size_t pos = 0;
+ const Ports *ports = NULL;
+ const Port *port = NULL;
+ const char *str = rtosc_argument(m,0).s;
+ const char *needle = rtosc_argument(m,1).s;
+
+ //zero out data
+ memset(types, 0, sizeof(types));
+ memset(args, 0, sizeof(args));
+
+ if(!*str) {
+ ports = &Master::ports;
+ } else {
+ const Port *port = Master::ports.apropos(rtosc_argument(m,0).s);
+ if(port)
+ ports = port->ports;
+ }
+
+ if(ports) {
+ //RTness not confirmed here
+ for(const Port &p:*ports) {
+ if(strstr(p.name, needle)!=p.name)
+ continue;
+ types[pos] = types[pos+1] = 's';
+ args[pos++].s = p.name;
+ args[pos++].s = p.metadata;
+ }
+ }
+
+ //Reply to requester
+ char buffer[1024];
+ size_t length = rtosc_amessage(buffer, 1024, "/paths", types, args);
+ if(length) {
+ lo_message msg = lo_message_deserialise((void*)buffer, length, NULL);
+ lo_address addr = lo_address_new_from_url(last_url.c_str());
+ if(addr)
+ lo_send_message(addr, buffer, msg);
+ }
+}
+
+int handler_function(const char *path, const char *types, lo_arg **argv,
+ int argc, lo_message msg, void *user_data)
+{
+ lo_address addr = lo_message_get_source(msg);
+ if(addr) {
+ const char *tmp = lo_address_get_url(addr);
+ if(tmp != last_url) {
+ uToB->write("/echo", "ss", "OSC_URL", tmp);
+ last_url = tmp;
+ }
+
+ }
+
+ char buffer[2048];
+ memset(buffer, 0, sizeof(buffer));
+ size_t size = 2048;
+ lo_message_serialise(msg, path, buffer, &size);
+ if(!strcmp(buffer, "/path-search") && !strcmp("ss", rtosc_argument_string(buffer))) {
+ path_search(buffer);
+ } else
+ uToB->raw_write(buffer);
+
+ return 0;
+}
+
+void osc_setup(void)
+{
+ server = lo_server_new_with_proto(NULL, LO_UDP, error_cb);
+ lo_server_add_method(server, NULL, NULL, handler_function, NULL);
+ fprintf(stderr, "lo server running on %d\n", lo_server_get_port(server));
+}
+
+/**
+ * - Fetches liblo messages and forward them to the backend
+ * - Grabs backend messages and distributes them to the frontends
+ */
+void osc_check(void)
+{
+ lo_server_recv_noblock(server, 100);
+ while(bToU->hasNext()) {
+ const char *rtmsg = bToU->read();
+ if(!strcmp(rtmsg, "/echo")
+ && !strcmp(rtosc_argument_string(rtmsg),"ss")
+ && !strcmp(rtosc_argument(rtmsg,0).s, "OSC_URL"))
+ curr_url = rtosc_argument(rtmsg,1).s;
+ else {
+ lo_message msg = lo_message_deserialise((void*)rtmsg,
+ rtosc_message_length(rtmsg, bToU->buffer_size()), NULL);
+
+ //Send to known url
+ if(!curr_url.empty()) {
+ lo_address addr = lo_address_new_from_url(curr_url.c_str());
+ lo_send_message(addr, rtmsg, msg);
+ }
+ }
+ }
+}
+
#ifndef DISABLE_GUI
@@ -139,6 +259,8 @@ void initprogram(void)
signal(SIGINT, sigterm_exit);
signal(SIGTERM, sigterm_exit);
+
+ osc_setup();
}
/*
@@ -537,6 +659,8 @@ int main(int argc, char *argv[])
done:
#endif
+ osc_check();
+
Fl::wait(0.02f);
#else
usleep(100000);