diff options
author | Florian Jung <flo@thinkpad.(none)> | 2011-01-06 20:16:19 +0100 |
---|---|---|
committer | Florian Jung <flo@thinkpad.(none)> | 2011-01-06 20:16:19 +0100 |
commit | e78131ccbbcb81da94e5992f788c6ea291a2050d (patch) | |
tree | ae15e6f8d77be250f168f1871c5a4de34c990abb /synth | |
parent | e8382521c1a35ad59efea5e8cebb915a67c0008e (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/Makefile | 4 | ||||
-rw-r--r-- | synth/channel.cpp | 50 | ||||
-rw-r--r-- | synth/globals.cpp | 2 | ||||
-rw-r--r-- | synth/globals.h | 2 | ||||
-rw-r--r-- | synth/jack.cpp | 4 | ||||
-rw-r--r-- | synth/main.cpp | 23 | ||||
-rw-r--r-- | synth/note.cpp | 5 | ||||
-rw-r--r-- | synth/note.h | 2 | ||||
-rw-r--r-- | synth/note_funcs.h | 20 | ||||
-rw-r--r-- | synth/note_loader.cpp | 44 | ||||
-rw-r--r-- | synth/note_loader.h | 13 | ||||
-rw-r--r-- | synth/note_skel.h | 2 | ||||
-rw-r--r-- | synth/programs.cpp | 7 | ||||
-rw-r--r-- | synth/programs.h | 6 |
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(); |