summaryrefslogtreecommitdiff
path: root/synth
diff options
context:
space:
mode:
authorFlorian Jung <flo@thinkpad.(none)>2011-01-06 20:16:19 +0100
committerFlorian Jung <flo@thinkpad.(none)>2011-01-06 20:16:19 +0100
commite78131ccbbcb81da94e5992f788c6ea291a2050d (patch)
treeae15e6f8d77be250f168f1871c5a4de34c990abb /synth
parente8382521c1a35ad59efea5e8cebb915a67c0008e (diff)
The synthesizer can now load the compiled notes
There are still issues: - filtertest.prog.so: output_note-message which is not true - huge size of the .so (48K are too much!)
Diffstat (limited to 'synth')
-rw-r--r--synth/Makefile4
-rw-r--r--synth/channel.cpp50
-rw-r--r--synth/globals.cpp2
-rw-r--r--synth/globals.h2
-rw-r--r--synth/jack.cpp4
-rw-r--r--synth/main.cpp23
-rw-r--r--synth/note.cpp5
-rw-r--r--synth/note.h2
-rw-r--r--synth/note_funcs.h20
-rw-r--r--synth/note_loader.cpp44
-rw-r--r--synth/note_loader.h13
-rw-r--r--synth/note_skel.h2
-rw-r--r--synth/programs.cpp7
-rw-r--r--synth/programs.h6
14 files changed, 161 insertions, 23 deletions
diff --git a/synth/Makefile b/synth/Makefile
index f84441c..c1d6dab 100644
--- a/synth/Makefile
+++ b/synth/Makefile
@@ -1,9 +1,9 @@
CXX=g++
-CFLAGS=-Wall -g
+CFLAGS=-Wall -O2
CXXFLAGS=$(CFLAGS)
LDFLAGS=-lm `pkg-config --cflags --libs jack`
-OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o
+OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o
BIN=synth
DEPENDFILE = .depend
diff --git a/synth/channel.cpp b/synth/channel.cpp
index ddad9fe..d70b199 100644
--- a/synth/channel.cpp
+++ b/synth/channel.cpp
@@ -5,6 +5,8 @@
#include "note.h"
+#include "note_funcs.h"
+
Channel::Channel()
{
@@ -34,7 +36,7 @@ void Channel::cleanup()
for (it=notes.begin(); it!=notes.end(); it++)
if ((*it)->still_active()==false)
{
- delete *it;
+ (*it)->destroy();
it=notes.erase(it);
}
}
@@ -86,15 +88,22 @@ void Channel::note_on(int note, int vel)
{
//if the program has changed, kill the previous note and
//create a new one
- delete n;
+ n->destroy();
notes.clear();
- notes.push_back( new Note(note,(float)vel/128.0,
- curr_prg,
- portamento_frames,
- pitchbend,
- program) );
-
+ NoteSkel *newnote=NULL;
+ if (curr_prg.create_func==NULL)
+ newnote = new Note(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+ else
+ newnote = curr_prg.create_func(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+
+ notes.push_back(newnote);
}
else //program did not change
{
@@ -122,11 +131,22 @@ void Channel::note_on(int note, int vel)
}
}
if (neednewnote)
- notes.push_back( new Note(note,(float)vel/128.0,
- curr_prg,
- portamento_frames,
- pitchbend,
- program) );
+ {
+ NoteSkel *newnote=NULL;
+ if (curr_prg.create_func==NULL)
+ newnote = new Note(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+ else
+ newnote = curr_prg.create_func(note,(float)vel/128.0,
+ curr_prg,
+ portamento_frames, pitchbend,
+ program);
+
+ notes.push_back(newnote);
+ }
+
apply_voice_limit();
}
}
@@ -167,7 +187,7 @@ void Channel::apply_voice_limit()
else
for (int i=0;i<diff;i++)
{
- delete (*it);
+ (*it)->destroy();
it=notes.erase(it);
}
}
@@ -313,7 +333,7 @@ void Channel::panic()
list<NoteSkel*>::iterator it;
for (it=notes.begin(); it!=notes.end();)
{
- delete *it;
+ (*it)->destroy();
it=notes.erase(it);
}
}
diff --git a/synth/globals.cpp b/synth/globals.cpp
index 5b256b3..d6af5f2 100644
--- a/synth/globals.cpp
+++ b/synth/globals.cpp
@@ -3,7 +3,7 @@
fixed_t **lfo[N_LFOS];
fixed_t *curr_lfo[N_LFOS+1];
-fixed_t wave[N_WAVEFORMS][WAVE_RES];
+fixed_t* wave[N_WAVEFORMS];
fixed_t sample_and_hold[N_LFO_LEVELS];
diff --git a/synth/globals.h b/synth/globals.h
index b7c9109..ad921c2 100644
--- a/synth/globals.h
+++ b/synth/globals.h
@@ -14,7 +14,7 @@ using namespace std;
extern fixed_t **lfo[N_LFOS];
extern fixed_t *curr_lfo[N_LFOS+1];
-extern fixed_t wave[N_WAVEFORMS][WAVE_RES];
+extern fixed_t* wave[N_WAVEFORMS];
extern fixed_t sample_and_hold[N_LFO_LEVELS];
diff --git a/synth/jack.cpp b/synth/jack.cpp
index 1c434f9..8d599de 100644
--- a/synth/jack.cpp
+++ b/synth/jack.cpp
@@ -329,8 +329,8 @@ int process_callback(jack_nframes_t nframes, void *notused)
if (lastframe>tmp+44100*4)
{
tmp2=2;
- channel[0]->event(0x90,87,5);
- channel[0]->set_controller(57, 127);
+ //channel[0]->event(0x90,87,5);
+ channel[0]->set_controller(58, 0);
cout << "BÄÄM2" << endl;
}
}
diff --git a/synth/main.cpp b/synth/main.cpp
index ae2e0d8..56c47b9 100644
--- a/synth/main.cpp
+++ b/synth/main.cpp
@@ -12,6 +12,7 @@
#include "programs.h"
#include "defines.h"
#include "globals.h"
+#include "note_loader.h"
using namespace std;
@@ -104,6 +105,24 @@ int main(int argc, char** argv)
try
{
program_settings[i]=parse(programfile[i]);
+
+ // try to load the appropriate .so file
+ if (access( (programfile[i]+".so").c_str(), R_OK ) == 0)
+ {
+ try
+ {
+ cout << "trying to load..."<<endl;
+ load_note_from_so(programfile[i]+".so", program_settings[i]);
+ }
+ catch (string err)
+ {
+ output_note("NOTE: could not load shared object '"+programfile[i]+".so"+"':\n"
+ " "+err+"\n"
+ " this is not fatal, the note has been loaded properly, but generic\n"
+ " unoptimized (slow) code will be used.");
+ }
+ }
+
}
catch (string err)
{
@@ -119,7 +138,9 @@ int main(int argc, char** argv)
}
}
-
+ for (i=0;i<N_WAVEFORMS;i++)
+ wave[i]=new fixed_t[WAVE_RES];
+
for (i=0;i<WAVE_RES;i++)
{
wave[0][i]=sin(i*2.0*3.141592654/WAVE_RES)*ONE;
diff --git a/synth/note.cpp b/synth/note.cpp
index 2f192f2..a0d6226 100644
--- a/synth/note.cpp
+++ b/synth/note.cpp
@@ -393,3 +393,8 @@ fixed_t Note::get_sample()
return out;
}
}
+
+void Note::destroy()
+{
+ delete this;
+}
diff --git a/synth/note.h b/synth/note.h
index aab471c..7c36d69 100644
--- a/synth/note.h
+++ b/synth/note.h
@@ -22,6 +22,8 @@ class Note : public NoteSkel
bool still_active();
void set_param(const parameter_t &p, fixed_t v);
+ void destroy();
+
private:
void do_ksl();
void do_ksr();
diff --git a/synth/note_funcs.h b/synth/note_funcs.h
new file mode 100644
index 0000000..2a9d3c0
--- /dev/null
+++ b/synth/note_funcs.h
@@ -0,0 +1,20 @@
+#ifndef __NOTE_FUNCS_H
+#define __NOTE_FUNCS_H
+
+#include <jack/jack.h>
+
+#include "fixed.h"
+#include <string>
+
+using namespace std;
+
+class NoteSkel;
+struct program_t;
+
+typedef void output_note_func_t(string s);
+typedef string IntToStr_func_t(int i);
+
+typedef NoteSkel* create_func_t (int, float, program_t&, jack_nframes_t, fixed_t, int);
+typedef void init_func_t(int sr, int fupfr, fixed_t **w, fixed_t **clfo, output_note_func_t* out_n, IntToStr_func_t* its);
+
+#endif
diff --git a/synth/note_loader.cpp b/synth/note_loader.cpp
new file mode 100644
index 0000000..b7ccc99
--- /dev/null
+++ b/synth/note_loader.cpp
@@ -0,0 +1,44 @@
+
+#include <iostream>
+#include <dlfcn.h>
+
+#include "note_loader.h"
+#include "programs.h"
+#include "note_funcs.h"
+#include "globals.h"
+
+using namespace std;
+
+void load_note_from_so(string file, program_t &prog)
+{
+ void *handle;
+
+ handle = dlopen(file.c_str(), RTLD_LAZY);
+
+ if (handle==NULL)
+ throw string("could not open shared object (")+string(dlerror())+string(")");
+
+ try
+ {
+ prog.create_func=(create_func_t*) dlsym(handle,"create_note");
+ if (prog.create_func==NULL)
+ throw string("could not find symbol create_note in shared object (")+dlerror()+")";
+
+ init_func_t* initfunc=(init_func_t*) dlsym(handle,"init_vars");
+ if (initfunc==NULL)
+ throw string("could not find symbol init_vars in shared object (")+dlerror()+")";
+
+ initfunc(samp_rate, filter_update_frames, wave, curr_lfo, &output_note, &IntToStr);
+
+
+
+ prog.dl_handle=handle;
+ }
+ catch (string err)
+ {
+ prog.create_func=NULL;
+ prog.dl_handle=NULL;
+ dlclose(handle);
+ throw err;
+ }
+}
diff --git a/synth/note_loader.h b/synth/note_loader.h
new file mode 100644
index 0000000..a922f3c
--- /dev/null
+++ b/synth/note_loader.h
@@ -0,0 +1,13 @@
+#ifndef __NOTE_LOADER_H__
+#define __NOTE_LOADER_H__
+
+#include <string>
+#include <jack/jack.h>
+
+#include "programs.h"
+
+using namespace std;
+
+void load_note_from_so(string file, program_t &prog); //throws string
+
+#endif
diff --git a/synth/note_skel.h b/synth/note_skel.h
index d3b5a13..6aebb8b 100644
--- a/synth/note_skel.h
+++ b/synth/note_skel.h
@@ -30,6 +30,8 @@ class NoteSkel
virtual void set_param(const parameter_t &p, fixed_t v)=0;
+ virtual void destroy()=0;
+
protected:
virtual void do_ksl()=0;
virtual void do_ksr()=0;
diff --git a/synth/programs.cpp b/synth/programs.cpp
index be82fed..094f209 100644
--- a/synth/programs.cpp
+++ b/synth/programs.cpp
@@ -49,6 +49,9 @@ program_t::program_t()
pfactor.fm=NULL;
pfactor.out=NULL;
+
+ create_func=NULL;
+ dl_handle=NULL;
}
program_t::~program_t()
@@ -115,6 +118,10 @@ program_t& program_t::operator=(const program_t &that)
memcpy(this->pfactor.fm[i], that.pfactor.fm[i], sizeof(param_factor_t)*n_osc);
}
+
+ this->create_func=that.create_func;
+ this->dl_handle=that.dl_handle;
+
return *this;
}
else
diff --git a/synth/programs.h b/synth/programs.h
index e0b409c..9d8d8cc 100644
--- a/synth/programs.h
+++ b/synth/programs.h
@@ -7,6 +7,7 @@
#include <list>
#include "fixed.h"
+#include "note_funcs.h"
#include <jack/jack.h>
using namespace std;
@@ -173,7 +174,10 @@ struct program_t
pfactor_formula_t pfactor;
-
+
+ void *dl_handle;
+ create_func_t *create_func;
+
program_t();
~program_t();